From 08840964b7afbce538b6c0c0786701b83cb35eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=94=A1=E5=8F=8A?= <522caiji@gmail.com> Date: Fri, 25 Sep 2026 15:47:53 +0800 Subject: [PATCH 1/4] feat(codex): add experimental Codex provider with native Responses streaming --- changelog/unreleased/codex-provider.md | 7 + docs/ARCHITECTURE_SUMMARY.md | 9 +- frontend/src/components/AddAccountModal.tsx | 4 +- frontend/src/components/CodexMark.tsx | 16 + frontend/src/components/ProviderMark.tsx | 4 + frontend/src/i18n/messages.ts | 4 + internal/app/app.go | 2 + internal/app/architecture_test.go | 2 +- internal/console/models.go | 2 +- internal/executor/chat.go | 32 +- internal/executor/prepare.go | 2 +- internal/executor/prepare_test.go | 1 + internal/gateway/native_responses.go | 110 +++ internal/gateway/native_responses_test.go | 66 ++ internal/gateway/responses.go | 12 +- internal/providers/codex/catalog.go | 104 +++ internal/providers/codex/classifier.go | 66 ++ internal/providers/codex/client.go | 783 ++++++++++++++++++ internal/providers/codex/credential.go | 144 ++++ internal/providers/codex/headers.go | 27 + internal/providers/codex/models.json | 196 +++++ internal/providers/codex/payload.go | 297 +++++++ internal/providers/codex/pkce.go | 34 + internal/providers/codex/quota.go | 83 ++ .../providers/codex/s04_interfaces_test.go | 249 ++++++ internal/providers/codex/sse.go | 453 ++++++++++ internal/providers/interfaces.go | 23 + internal/providers/registry.go | 24 + ...t-6OfHAVPl.js => TrafficChart-C6BPz1n1.js} | 2 +- .../webui/static/assets/index-C4p-2Dwo.js | 28 - ...{index-Dag5H4-P.css => index-CgxCaPsN.css} | 2 +- .../webui/static/assets/index-DOe_Z27O.js | 28 + internal/webui/static/index.html | 4 +- 33 files changed, 2776 insertions(+), 44 deletions(-) create mode 100644 changelog/unreleased/codex-provider.md create mode 100644 frontend/src/components/CodexMark.tsx create mode 100644 internal/gateway/native_responses.go create mode 100644 internal/gateway/native_responses_test.go create mode 100644 internal/providers/codex/catalog.go create mode 100644 internal/providers/codex/classifier.go create mode 100644 internal/providers/codex/client.go create mode 100644 internal/providers/codex/credential.go create mode 100644 internal/providers/codex/headers.go create mode 100644 internal/providers/codex/models.json create mode 100644 internal/providers/codex/payload.go create mode 100644 internal/providers/codex/pkce.go create mode 100644 internal/providers/codex/quota.go create mode 100644 internal/providers/codex/s04_interfaces_test.go create mode 100644 internal/providers/codex/sse.go rename internal/webui/static/assets/{TrafficChart-6OfHAVPl.js => TrafficChart-C6BPz1n1.js} (99%) delete mode 100644 internal/webui/static/assets/index-C4p-2Dwo.js rename internal/webui/static/assets/{index-Dag5H4-P.css => index-CgxCaPsN.css} (93%) create mode 100644 internal/webui/static/assets/index-DOe_Z27O.js diff --git a/changelog/unreleased/codex-provider.md b/changelog/unreleased/codex-provider.md new file mode 100644 index 00000000..e5dddc84 --- /dev/null +++ b/changelog/unreleased/codex-provider.md @@ -0,0 +1,7 @@ +### English + +- Add `codex` provider: OpenAI Codex accounts backed by a ChatGPT subscription, with browser OAuth login, automatic token refresh, streaming chat, model catalog, and rate-limit window display. + +### 中文 + +- 新增 `codex` provider:基于 ChatGPT 订阅的 OpenAI Codex 账号,支持浏览器 OAuth 登录、自动刷新 token、流式聊天、模型目录和限速窗口展示。 diff --git a/docs/ARCHITECTURE_SUMMARY.md b/docs/ARCHITECTURE_SUMMARY.md index 1a1ce8fb..f7128d26 100644 --- a/docs/ARCHITECTURE_SUMMARY.md +++ b/docs/ARCHITECTURE_SUMMARY.md @@ -5,8 +5,8 @@ scope: [backend, runtime, providers, routing, console] status: canonical read-when: 需要快速理解后端分层、请求路径、运行时和 provider 扩展边界时 summary: 面向贡献者和 AI 的精简架构摘要;详细协议、里程碑和本地运维资料不在本文维护。 -related: [AGENTS.md, CONTRIBUTING.md, docs/DESIGN.md, docs/REFACTORING.md] -last-updated: 2026-09-20 +related: [AGENTS.md, CONTRIBUTING.md, docs/DESIGN.md, docs/REFACTORING.md, docs/NATIVE_PROTOCOL_REQUESTS.md] +last-updated: 2026-09-24 --- # CLI2API 架构摘要 @@ -85,6 +85,11 @@ cmd/server - 管理接口必须认证;默认只绑定本机,不要直接暴露 host 端口到公网。 - 不提交 `.env`、auth blob、token、raw capture、主机 IP、私有部署 runbook。 +## 待实施的原生协议请求设计 + +三个公共入口与上游协议的对应关系、双路径分派及 Responses 原生请求的演进方案,见 [原生协议请求架构与渐进改造方案](NATIVE_PROTOCOL_REQUESTS.md)。 +该文档状态为 `proposed`:保留 `ChatRequest` 兼容路径,通过显式请求封装和可选原生能力避免同协议往返转换;不是当前实现或已发布能力声明。 + ## 修改前检查 - 先读 `AGENTS.md`,再按任务需要读 `DESIGN.md`、`CONTRIBUTING.md` 或本摘要。 diff --git a/frontend/src/components/AddAccountModal.tsx b/frontend/src/components/AddAccountModal.tsx index 73533def..af32886b 100644 --- a/frontend/src/components/AddAccountModal.tsx +++ b/frontend/src/components/AddAccountModal.tsx @@ -52,6 +52,7 @@ const labelKeys: Record = { 'trae-cn': 'accountTypeTraeCN', 'devin-global': 'accountTypeDevinGlobal', 'command-global': 'accountTypeCommandGlobal', + 'codex-global': 'accountTypeCodexGlobal', } const hintKeys: Record = { @@ -62,6 +63,7 @@ const hintKeys: Record = { 'trae-cn': 'accountTypeTraeCNHint', 'devin-global': 'accountTypeDevinGlobalHint', 'command-global': 'accountTypeCommandGlobalHint', + 'codex-global': 'accountTypeCodexGlobalHint', } function AccountTypeSkeleton({ ariaLabel }: { ariaLabel: string }) { @@ -186,7 +188,7 @@ export function AddAccountModal({ isOpen, onClose, onAdded }: Props) { // so the wizard opens on the PAT tab instead of the browser tab. const hasBrowserLogin = activeOption?.descriptor.capabilities?.browser_login !== false const showDropSystem = activeOption?.provider === 'workbuddy' - const showCallbackPaste = activeOption?.provider === 'trae' || activeOption?.provider === 'devin' + const showCallbackPaste = activeOption?.provider === 'trae' || activeOption?.provider === 'devin' || activeOption?.provider === 'codex' const busy = phase === 'busy' || phase === 'polling' const settingsLocked = Boolean(createdId.current) || busy const isDone = phase === 'done' diff --git a/frontend/src/components/CodexMark.tsx b/frontend/src/components/CodexMark.tsx new file mode 100644 index 00000000..475a0a0c --- /dev/null +++ b/frontend/src/components/CodexMark.tsx @@ -0,0 +1,16 @@ +type Props = { + size?: number + className?: string +} + +export function CodexMark({ size = 16, className = '' }: Props) { + return ( + + ) +} diff --git a/frontend/src/components/ProviderMark.tsx b/frontend/src/components/ProviderMark.tsx index 0fd8bfe3..fdea3716 100644 --- a/frontend/src/components/ProviderMark.tsx +++ b/frontend/src/components/ProviderMark.tsx @@ -1,4 +1,5 @@ import { CommandMark } from '@/components/CommandMark' +import { CodexMark } from '@/components/CodexMark' import { DevinMark } from '@/components/DevinMark' import { QoderMark } from '@/components/QoderMark' import { TraeMark } from '@/components/TraeMark' @@ -25,5 +26,8 @@ export function ProviderMark({ provider, size = 16, className = '' }: Props) { if (id === 'command') { return } + if (id === 'codex') { + return + } return } diff --git a/frontend/src/i18n/messages.ts b/frontend/src/i18n/messages.ts index 8b26b748..4b2d9a53 100644 --- a/frontend/src/i18n/messages.ts +++ b/frontend/src/i18n/messages.ts @@ -565,6 +565,8 @@ export const messages: Record = { accountTypeDevinGlobalHint: 'Experimental Devin Global via browser OAuth or session token import', accountTypeCommandGlobal: 'Command Code', accountTypeCommandGlobalHint: 'Command Code via a pasted user_… key. Speaks the CLI /alpha/generate protocol, so every plan works — including the $1 Go plan.', + accountTypeCodexGlobal: 'Codex', + accountTypeCodexGlobalHint: 'OpenAI Codex (ChatGPT subscription) via browser OAuth or imported credential', addAccountDesc: 'Create an isolated account session. Each account keeps its own runtime home.', tabBrowser: 'Browser login', tabPat: 'PAT', @@ -1216,6 +1218,8 @@ export const messages: Record = { accountTypeDevinGlobalHint: '实验性 Devin 国际版:浏览器 OAuth 或导入 session token', accountTypeCommandGlobal: 'Command Code', accountTypeCommandGlobalHint: '粘贴 user_… 密钥接入。走 CLI 的 /alpha/generate 协议,所有档位均可用(含 $1 Go 套餐)。', + accountTypeCodexGlobal: 'Codex', + accountTypeCodexGlobalHint: 'OpenAI Codex(ChatGPT 订阅):浏览器 OAuth 或导入凭证', addAccountDesc: '创建一个隔离会话并登录。每个账号使用独立的运行时目录。', tabBrowser: '浏览器登录', tabPat: 'PAT', diff --git a/internal/app/app.go b/internal/app/app.go index af576446..ff179de7 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -22,6 +22,7 @@ import ( apigateway "github.com/caigee-cmd/cli2api/internal/gateway" applogs "github.com/caigee-cmd/cli2api/internal/logs" "github.com/caigee-cmd/cli2api/internal/providers" + "github.com/caigee-cmd/cli2api/internal/providers/codex" "github.com/caigee-cmd/cli2api/internal/providers/command" "github.com/caigee-cmd/cli2api/internal/providers/devin" "github.com/caigee-cmd/cli2api/internal/providers/qoder" @@ -111,6 +112,7 @@ func New(cfg config.Config) *App { providerReg.Register(trae.NewClient(store).Adapter()) providerReg.Register(devin.NewClient(store).Adapter()) providerReg.Register(command.NewClient(store).Adapter()) + providerReg.Register(codex.NewClient(store).Adapter()) qoderClient := qoder.NewClient() qoderClient.Bind(manager.AccountURL, manager.ProxyAPIKey) providerReg.Register(qoderClient.Adapter()) diff --git a/internal/app/architecture_test.go b/internal/app/architecture_test.go index 4353d3d0..f9a01d5e 100644 --- a/internal/app/architecture_test.go +++ b/internal/app/architecture_test.go @@ -176,7 +176,7 @@ func isConcreteProvider(imp string) bool { rest := strings.TrimPrefix(imp, prefix) root, _, _ := strings.Cut(rest, "/") switch root { - case "qoder", "workbuddy", "trae", "devin", "command": + case "qoder", "workbuddy", "trae", "devin", "command", "codex": return true default: return false diff --git a/internal/console/models.go b/internal/console/models.go index e39aa8bf..74ca4479 100644 --- a/internal/console/models.go +++ b/internal/console/models.go @@ -11,7 +11,7 @@ import ( func splitModelSettingPath(raw, queryProvider string) (provider, modelKey string) { raw = strings.TrimPrefix(raw, "/api/models/") provider = strings.ToLower(strings.TrimSpace(queryProvider)) - for _, prefix := range []string{"trae/", "workbuddy/", "qoder/", "devin/", "command/"} { + for _, prefix := range []string{"trae/", "workbuddy/", "qoder/", "devin/", "command/", "codex/"} { if strings.HasPrefix(strings.ToLower(raw), prefix) { provider = strings.TrimSuffix(prefix, "/") raw = raw[len(prefix):] diff --git a/internal/executor/chat.go b/internal/executor/chat.go index b56453c1..8c21a5c3 100644 --- a/internal/executor/chat.go +++ b/internal/executor/chat.go @@ -64,6 +64,9 @@ type StreamResult struct { TTFBMs int Routing string ReasoningLevel string + // NativeResponses marks the body as an upstream OpenAI Responses SSE stream + // that /v1/responses can relay verbatim instead of translating. + NativeResponses bool } type requestIDKey struct{} @@ -891,13 +894,22 @@ func (e ChatExecutor) chatInProcessNonStreamAttempt(ctx context.Context, item It }, Classified{}, nil } -func (e ChatExecutor) chatInProcessStreamAttempt(ctx context.Context, item Item, req translate.ChatRequest, attemptIndex int) (StreamResult, Classified, error) { +func (e ChatExecutor) chatInProcessStreamAttempt(ctx context.Context, item Item, req translate.ChatRequest, attemptIndex int, preferNativeResponses bool) (StreamResult, Classified, error) { adapter, _ := e.Providers.Get(itemProvider(item)) if adapter.Chat == nil { return StreamResult{}, Classified{}, fmt.Errorf("provider %s does not implement chat", item.Provider) } started := time.Now() - resp, resolved, err := adapter.Chat.ChatStream(ctx, item.ID, sanitizeForItem(item, req)) + var resp *http.Response + var resolved providers.ResolvedChat + var err error + nativeResponses := false + if preferNativeResponses && adapter.NativeResponses != nil { + resp, resolved, err = adapter.NativeResponses.ResponsesStream(ctx, item.ID, sanitizeForItem(item, req)) + nativeResponses = err == nil + } else { + resp, resolved, err = adapter.Chat.ChatStream(ctx, item.ID, sanitizeForItem(item, req)) + } if err == nil { logResolvedReasoning(ctx, "chat_stream", item, req.Model, resolved.ReasoningLevel) } @@ -929,7 +941,7 @@ func (e ChatExecutor) chatInProcessStreamAttempt(ctx context.Context, item Item, AttemptIndex: attemptIndex, AccountID: item.ID, StartedAt: started, FinishedAt: &headerAt, Status: accounts.AttemptStatusOK, HTTPStatus: ptrInt(http.StatusOK), LatencyMs: &ttfb, }) - return StreamResult{Response: resp, AccountID: item.ID, Provider: item.Provider, TTFBMs: ttfb, ReasoningLevel: resolved.ReasoningLevel}, Classified{}, nil + return StreamResult{Response: resp, AccountID: item.ID, Provider: item.Provider, TTFBMs: ttfb, ReasoningLevel: resolved.ReasoningLevel, NativeResponses: nativeResponses}, Classified{}, nil } func (e ChatExecutor) classifyInProcessError(err error) Classified { return ClassifyError(err) } @@ -1028,6 +1040,18 @@ func (e ChatExecutor) streamHTTPClient() *http.Client { } func (e ChatExecutor) ChatStreamProxy(ctx context.Context, req translate.ChatRequest, prefer, providerFilter string) (result StreamResult, returnErr error) { + return e.chatStreamProxy(ctx, req, prefer, providerFilter, false) +} + +// ChatStreamProxyNativeResponses is the /v1/responses variant: when the picked +// account's provider implements NativeResponsesStreamer the upstream body is +// relayed verbatim and StreamResult.NativeResponses is set, so the gateway can +// skip translation. +func (e ChatExecutor) ChatStreamProxyNativeResponses(ctx context.Context, req translate.ChatRequest, prefer, providerFilter string) (result StreamResult, returnErr error) { + return e.chatStreamProxy(ctx, req, prefer, providerFilter, true) +} + +func (e ChatExecutor) chatStreamProxy(ctx context.Context, req translate.ChatRequest, prefer, providerFilter string, preferNativeResponses bool) (result StreamResult, returnErr error) { loop := e.newRouteLoop(ctx, prefer, providerFilter, req) defer func() { result.Routing = loop.routing.Source }() payload, err := json.Marshal(qoder.BuildChatPayload(req, true)) @@ -1045,7 +1069,7 @@ func (e ChatExecutor) ChatStreamProxy(ctx context.Context, req translate.ChatReq return StreamResult{}, pickErr } if isInProcessItem(item) { - result, classified, err := e.chatInProcessStreamAttempt(ctx, item, req, i) + result, classified, err := e.chatInProcessStreamAttempt(ctx, item, req, i, preferNativeResponses) if err == nil { result.AttemptCount = i + 1 e.observeRouting(&loop.routing, result.AccountID) diff --git a/internal/executor/prepare.go b/internal/executor/prepare.go index 3654da79..80b6e3ef 100644 --- a/internal/executor/prepare.go +++ b/internal/executor/prepare.go @@ -140,7 +140,7 @@ func (e ChatExecutor) Prepare(in PrepareInput) (PreparedRequest, error) { // "/" model id. Command Code's own model ids are org-namespaced // ("deepseek/…", "moonshotai/…"), so its provider prefix sits in front of an // already-namespaced id ("command/deepseek/…"). -var providerPrefixes = []string{"qoder/", "workbuddy/", "trae/", "devin/", "command/"} +var providerPrefixes = []string{"qoder/", "workbuddy/", "trae/", "devin/", "command/", "codex/"} func ProviderPrefix(model string) string { model = strings.TrimSpace(model) diff --git a/internal/executor/prepare_test.go b/internal/executor/prepare_test.go index 5a7435d4..642c2844 100644 --- a/internal/executor/prepare_test.go +++ b/internal/executor/prepare_test.go @@ -227,6 +227,7 @@ func TestProviderPrefixRecognizesCommand(t *testing.T) { "workbuddy/deepseek-v4-pro": "workbuddy", "trae/kimi-k2.6": "trae", "devin/swe-2": "devin", + "codex/gpt-5.5": "codex", "command/deepseek/deepseek-v4-pro": "command", "command/moonshotai/Kimi-K3": "command", // A bare org-namespaced Command Code id must NOT be read as a provider. diff --git a/internal/gateway/native_responses.go b/internal/gateway/native_responses.go new file mode 100644 index 00000000..44cf99b5 --- /dev/null +++ b/internal/gateway/native_responses.go @@ -0,0 +1,110 @@ +package gateway + +import ( + "bufio" + "encoding/json" + "io" + "strings" + "time" + + "github.com/caigee-cmd/cli2api/internal/executor" +) + +// RelayNativeResponsesStream relays an upstream OpenAI Responses SSE body +// verbatim while observing the frames needed for accounting: first-token +// timing, terminal status, and token usage. It writes nothing of its own — +// the upstream already emits a well-formed event stream including +// response.created / response.completed. +func RelayNativeResponsesStream(writer io.Writer, body io.Reader) (StreamRelayStats, error) { + var stats StreamRelayStats + scanner := bufio.NewScanner(body) + scanner.Buffer(make([]byte, 0, 64*1024), maxSSELineSize) + var frame []string + var sawTerminal bool + flush := func() error { + if len(frame) == 0 { + return nil + } + eventName, data := parseSSEFrame(frame) + if _, err := io.WriteString(writer, strings.Join(frame, "\n")+"\n\n"); err != nil { + frame = nil + return &StreamRelayWriteError{err: err} + } + frame = nil + if classified := classifyStreamSSEError(eventName, data); classified != nil { + return classified + } + payload := strings.TrimSpace(data) + if payload == "" || payload == "[DONE]" { + return nil + } + var obj struct { + Type string `json:"type"` + Response struct { + Status string `json:"status"` + Usage struct { + InputTokens int `json:"input_tokens"` + OutputTokens int `json:"output_tokens"` + TotalTokens int `json:"total_tokens"` + } `json:"usage"` + } `json:"response"` + } + if json.Unmarshal([]byte(payload), &obj) != nil { + return nil + } + if stats.FirstTokenAt == nil && isFirstTokenEvent(obj.Type) { + now := time.Now() + stats.FirstTokenAt = &now + } + switch obj.Type { + case "response.completed": + sawTerminal = true + stats.FinishReason = "stop" + if obj.Response.Usage.InputTokens > 0 { + stats.PromptTokens = intPtr(obj.Response.Usage.InputTokens) + } + if obj.Response.Usage.OutputTokens > 0 { + stats.CompletionTokens = intPtr(obj.Response.Usage.OutputTokens) + } + case "response.incomplete": + sawTerminal = true + stats.FinishReason = "length" + if obj.Response.Usage.InputTokens > 0 { + stats.PromptTokens = intPtr(obj.Response.Usage.InputTokens) + } + if obj.Response.Usage.OutputTokens > 0 { + stats.CompletionTokens = intPtr(obj.Response.Usage.OutputTokens) + } + case "response.failed", "error": + sawTerminal = true + stats.FinishReason = "error" + } + return nil + } + for scanner.Scan() { + line := strings.TrimSuffix(scanner.Text(), "\r") + if line == "" { + if err := flush(); err != nil { + return stats, err + } + continue + } + frame = append(frame, line) + } + if err := scanner.Err(); err != nil { + return stats, executor.StreamReadError(err) + } + if err := flush(); err != nil { + return stats, err + } + if !sawTerminal { + return stats, executor.StreamIncompleteError() + } + return stats, nil +} + +func isFirstTokenEvent(eventType string) bool { + return strings.HasSuffix(eventType, ".delta") +} + +func intPtr(v int) *int { return &v } diff --git a/internal/gateway/native_responses_test.go b/internal/gateway/native_responses_test.go new file mode 100644 index 00000000..e9e4e6a7 --- /dev/null +++ b/internal/gateway/native_responses_test.go @@ -0,0 +1,66 @@ +package gateway + +import ( + "bytes" + "strings" + "testing" +) + +func TestRelayNativeResponsesStreamPassthrough(t *testing.T) { + upstream := strings.Join([]string{ + `event: response.created`, + `data: {"type":"response.created","response":{"id":"resp_1","status":"in_progress"}}`, + ``, + `event: response.output_text.delta`, + `data: {"type":"response.output_text.delta","delta":"hello"}`, + ``, + `event: response.completed`, + `data: {"type":"response.completed","response":{"status":"completed","usage":{"input_tokens":12,"output_tokens":3,"total_tokens":15},"output":[]}}`, + ``, + }, "\n") + var out bytes.Buffer + stats, err := RelayNativeResponsesStream(&out, strings.NewReader(upstream)) + if err != nil { + t.Fatal(err) + } + // Every upstream frame must be relayed byte-for-byte (normalized newlines). + if !strings.Contains(out.String(), `response.output_text.delta`) || !strings.Contains(out.String(), `"delta":"hello"`) { + t.Fatalf("missing delta passthrough:\n%s", out.String()) + } + if !strings.Contains(out.String(), `response.completed`) { + t.Fatalf("missing terminal passthrough:\n%s", out.String()) + } + if stats.FinishReason != "stop" { + t.Fatalf("finish %q", stats.FinishReason) + } + if stats.PromptTokens == nil || *stats.PromptTokens != 12 || stats.CompletionTokens == nil || *stats.CompletionTokens != 3 { + t.Fatalf("usage %+v", stats) + } + if stats.FirstTokenAt == nil { + t.Fatal("expected first-token timing") + } +} + +func TestRelayNativeResponsesStreamIncomplete(t *testing.T) { + upstream := "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"delta\":\"hi\"}\n\n" + stats, err := RelayNativeResponsesStream(&bytes.Buffer{}, strings.NewReader(upstream)) + if err == nil { + t.Fatal("expected incomplete error") + } + _ = stats +} + +func TestRelayNativeResponsesStreamIncompleteStatus(t *testing.T) { + upstream := strings.Join([]string{ + `event: response.incomplete`, + `data: {"type":"response.incomplete","response":{"status":"incomplete","usage":{"input_tokens":5,"output_tokens":100}}}`, + ``, + }, "\n") + stats, err := RelayNativeResponsesStream(&bytes.Buffer{}, strings.NewReader(upstream)) + if err != nil { + t.Fatal(err) + } + if stats.FinishReason != "length" { + t.Fatalf("finish %q", stats.FinishReason) + } +} diff --git a/internal/gateway/responses.go b/internal/gateway/responses.go index 688862b4..991503ac 100644 --- a/internal/gateway/responses.go +++ b/internal/gateway/responses.go @@ -60,7 +60,7 @@ func (h *Handler) HandleResponses(w http.ResponseWriter, r *http.Request) { } func (h *Handler) handleResponsesStream(w http.ResponseWriter, r *http.Request, execution Execution) { - upstream, err := h.Executor.ChatStreamProxy(execution.Context, execution.Request, execution.Prefer, execution.ProviderFilter) + upstream, err := h.Executor.ChatStreamProxyNativeResponses(execution.Context, execution.Request, execution.Prefer, execution.ProviderFilter) if err != nil { h.finishCompatibility(execution, upstream.AccountID, upstream.Provider, upstream.Routing, accounts.RequestStatusError, upstream.TTFBMs, nil, err, upstream.AttemptCount, upstream.ReasoningLevel) writeCompatibilityOpenAIError(w, err) @@ -74,7 +74,15 @@ func (h *Handler) handleResponsesStream(w http.ResponseWriter, r *http.Request, flusher.Flush() } writer := compatibilityStreamWriter(w) - stats, relayErr := RelayResponsesStream(writer, upstream.Response.Body, execution.RequestID, firstNonEmpty(execution.PublicModel, execution.Request.Model), execution.Request.ResponseToolNames) + var stats StreamRelayStats + var relayErr error + if upstream.NativeResponses { + // The upstream already speaks the Responses protocol: relay verbatim and + // observe the terminal event for usage/finish accounting. + stats, relayErr = RelayNativeResponsesStream(writer, upstream.Response.Body) + } else { + stats, relayErr = RelayResponsesStream(writer, upstream.Response.Body, execution.RequestID, firstNonEmpty(execution.PublicModel, execution.Request.Model), execution.Request.ResponseToolNames) + } status := streamRequestStatus(relayErr) if relayErr == nil { status = responsesRequestStatus(stats.FinishReason) diff --git a/internal/providers/codex/catalog.go b/internal/providers/codex/catalog.go new file mode 100644 index 00000000..94752f80 --- /dev/null +++ b/internal/providers/codex/catalog.go @@ -0,0 +1,104 @@ +package codex + +import ( + _ "embed" + "encoding/json" + "strings" + + "github.com/caigee-cmd/cli2api/internal/providers" +) + +//go:embed models.json +var catalogJSON []byte + +// catalogEntry mirrors the slim fields extracted from the official codex client +// model list (CLIProxyAPI internal/registry/models/codex_client_models.json). +type catalogEntry struct { + Slug string `json:"slug"` + DisplayName string `json:"display_name"` + ContextWindow int `json:"context_window"` + MaxContextWindow int `json:"max_context_window"` + DefaultReasoning string `json:"default_reasoning_level"` + ReasoningLevels []string `json:"supported_reasoning_levels"` + InputModalities []string `json:"input_modalities"` + PreferWebsockets bool `json:"prefer_websockets"` + UseResponsesLite bool `json:"use_responses_lite"` + SupportedInAPI bool `json:"supported_in_api"` +} + +var catalog []catalogEntry + +func init() { + var doc struct { + Models []catalogEntry `json:"models"` + } + if err := json.Unmarshal(catalogJSON, &doc); err == nil { + catalog = doc.Models + } +} + +// lookupModel resolves a request model to its catalog entry. The public model +// id is the upstream slug verbatim. +func lookupModel(model string) (catalogEntry, bool) { + model = strings.TrimSpace(model) + for _, entry := range catalog { + if entry.Slug == model { + return entry, true + } + } + return catalogEntry{}, false +} + +func entryModelInfo(entry catalogEntry) providers.ModelInfo { + images := false + for _, modality := range entry.InputModalities { + if modality == "image" { + images = true + } + } + options := providers.UniqueReasoningOptions(entry.ReasoningLevels) + caps := providers.ModelCapabilities{ + ContextWindow: entry.ContextWindow, + ContextWindowMax: entry.MaxContextWindow, + Tools: true, + Images: images, + Reasoning: len(options) > 0, + ReasoningOptions: options, + ReasoningDefault: providers.NormalizeReasoningLevel(entry.DefaultReasoning), + ReasoningType: "effort", + } + return providers.ModelInfo{ + NativeModel: entry.Slug, + PublicModel: entry.Slug, + DisplayName: entry.DisplayName, + Capabilities: caps, + } +} + +// catalogModelInfos returns every model the catalog declares API-servable. +func catalogModelInfos() []providers.ModelInfo { + out := make([]providers.ModelInfo, 0, len(catalog)) + for _, entry := range catalog { + if !entry.SupportedInAPI { + continue + } + out = append(out, entryModelInfo(entry)) + } + return out +} + +// capsFor returns the catalog capabilities for a model, or zero caps when the +// model is unknown. +func capsFor(model string) providers.ModelCapabilities { + if entry, ok := lookupModel(model); ok { + return entryModelInfo(entry).Capabilities + } + return providers.ModelCapabilities{} +} + +// usesResponsesLite reports whether the model must be sent under the +// responses-lite variant (parallel_tool_calls forced off upstream). +func usesResponsesLite(model string) bool { + entry, ok := lookupModel(model) + return ok && entry.UseResponsesLite +} diff --git a/internal/providers/codex/classifier.go b/internal/providers/codex/classifier.go new file mode 100644 index 00000000..95f8787c --- /dev/null +++ b/internal/providers/codex/classifier.go @@ -0,0 +1,66 @@ +package codex + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/caigee-cmd/cli2api/internal/accounts" + "github.com/caigee-cmd/cli2api/internal/providers" +) + +// Classify maps codex upstream errors onto the internal taxonomy. The ChatGPT +// backend returns OpenAI-style error JSON plus Cloudflare HTML on edge blocks. +func Classify(status int, body string) providers.ClassifiedError { + text := strings.ToLower(body) + // Cloudflare edge rejection (1010 etc.) is a body match, not a status. + if strings.Contains(text, "cloudflare") || strings.Contains(text, "error 1010") || strings.Contains(text, "= 500: + return providers.ClassifiedError{Kind: accounts.KindUnavailable, Status: status, Message: firstNonEmpty(message, strings.TrimSpace(body))} + } + return providers.ClassifiedError{} +} + +// parseErrorBody reads {"error":{"code","message"}} plus the flat +// {"code","detail"} shape some codex endpoints use. +func parseErrorBody(body string) (code, message string) { + var env struct { + Error struct { + Code string `json:"code"` + Message string `json:"message"` + Type string `json:"type"` + } `json:"error"` + Code string `json:"code"` + Detail string `json:"detail"` + Message string `json:"message"` + } + if json.Unmarshal([]byte(body), &env) != nil { + return "", "" + } + code = firstNonEmpty(env.Error.Code, env.Error.Type, env.Code) + message = firstNonEmpty(env.Error.Message, env.Detail, env.Message) + return code, message +} + +func classifiedErrorf(status int, body []byte, format string, args ...any) error { + classified := Classify(status, string(body)) + return &providers.Error{ + Kind: classified.Kind, + Status: classified.Status, + Message: fmt.Sprintf(format, args...), + } +} diff --git a/internal/providers/codex/client.go b/internal/providers/codex/client.go new file mode 100644 index 00000000..fe52a3dc --- /dev/null +++ b/internal/providers/codex/client.go @@ -0,0 +1,783 @@ +package codex + +import ( + "bytes" + "context" + "crypto/rand" + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "encoding/json" + "fmt" + "io" + "net" + "net/http" + "net/url" + "strings" + "sync" + "time" + + "github.com/caigee-cmd/cli2api/internal/accounts" + "github.com/caigee-cmd/cli2api/internal/auth" + "github.com/caigee-cmd/cli2api/internal/providers" + proxyutil "github.com/caigee-cmd/cli2api/internal/proxy" + "github.com/caigee-cmd/cli2api/internal/translate" +) + +// Store is the persistence surface the adapter needs. +type Store interface { + Get(ctx context.Context, id string) (accounts.Account, error) + LoadCredentialPayload(ctx context.Context, accountID string) (string, []byte, error) + SaveCredentialPayload(ctx context.Context, accountID, format string, payload []byte) error + Observe(ctx context.Context, id, remoteUID, status, lastError, lastKind string) error +} + +// SecretReader is optional; missing it means no global proxy. +type SecretReader interface { + GetSecret(context.Context, string) (string, bool, error) +} + +type loginPending struct { + state string + codeVerifier string + createdAt time.Time + done bool + failed bool + message string + credential Credential +} + +type Client struct { + store Store + http *http.Client + + transports proxyutil.TransportCache + + mu sync.Mutex + pending map[string]*loginPending + pendingStates map[string]string // oauth state → accountID + listener net.Listener + refresh map[string]*refreshCall + quotaCache map[string]*providers.QuotaInfo +} + +// refreshCall singleflights token refresh by account so concurrent requests +// share one round-trip (OpenAI rotates refresh tokens; a second exchange with +// the same token returns refresh_token_reused). +type refreshCall struct { + done chan struct{} + cred Credential + err error +} + +const catalogTimeout = 15 * time.Second + +func NewClient(store Store) *Client { + return &Client{ + store: store, + http: &http.Client{ + Timeout: 120 * time.Second, + CheckRedirect: func(*http.Request, []*http.Request) error { + return http.ErrUseLastResponse + }, + }, + pending: map[string]*loginPending{}, + pendingStates: map[string]string{}, + refresh: map[string]*refreshCall{}, + } +} + +func (c *Client) globalProxy(ctx context.Context) (string, error) { + store, ok := c.store.(SecretReader) + if !ok { + return "", nil + } + value, found, err := store.GetSecret(ctx, "proxy_url") + if err != nil { + return "", fmt.Errorf("load global proxy setting: %w", err) + } + if !found { + return "", nil + } + return strings.TrimSpace(value), nil +} + +func (c *Client) effectiveProxy(ctx context.Context, accountID string) (string, error) { + account, err := c.store.Get(ctx, accountID) + if err != nil { + return "", err + } + if value := strings.TrimSpace(account.ProxyURL); value != "" { + return value, nil + } + return c.globalProxy(ctx) +} + +func (c *Client) httpClient(ctx context.Context, accountID string) (*http.Client, error) { + rawProxy, err := c.effectiveProxy(ctx, accountID) + if err != nil { + return nil, err + } + client := *c.http + transport, err := c.transports.Get(rawProxy) + if err != nil { + return nil, err + } + if transport != nil { + client.Transport = transport + } + return &client, nil +} + +func (c *Client) do(ctx context.Context, accountID, method, rawURL string, body []byte, setHeaders func(http.Header)) ([]byte, int, error) { + var reader io.Reader + if body != nil { + reader = bytes.NewReader(body) + } + req, err := http.NewRequestWithContext(ctx, method, rawURL, reader) + if err != nil { + return nil, 0, err + } + if setHeaders != nil { + setHeaders(req.Header) + } + client, err := c.httpClient(ctx, accountID) + if err != nil { + return nil, 0, err + } + resp, err := client.Do(req) + if err != nil { + return nil, 0, err + } + defer resp.Body.Close() + payload, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + if err != nil { + return nil, resp.StatusCode, err + } + return payload, resp.StatusCode, nil +} + +// --------------------------------------------------------------------------- +// Login +// --------------------------------------------------------------------------- + +func (c *Client) StartLogin(ctx context.Context, accountID string) (providers.LoginSession, error) { + if err := c.ensureCallback(); err != nil { + return providers.LoginSession{}, err + } + state := randomHex(16) + verifier, challenge, err := pkcePair() + if err != nil { + return providers.LoginSession{}, err + } + c.mu.Lock() + c.pending[accountID] = &loginPending{ + state: state, + codeVerifier: verifier, + createdAt: time.Now(), + } + c.pendingStates[state] = accountID + c.mu.Unlock() + + params := url.Values{ + "client_id": {ClientID}, + "response_type": {"code"}, + "redirect_uri": {redirectURI}, + "scope": {Scope}, + "state": {state}, + "code_challenge": {challenge}, + "code_challenge_method": {"S256"}, + "prompt": {"login"}, + "id_token_add_organizations": {"true"}, + "codex_cli_simplified_flow": {"true"}, + } + return providers.LoginSession{ + AuthURL: AuthURL + "?" + params.Encode(), + State: state, + }, nil +} + +func (c *Client) PollLogin(ctx context.Context, accountID string) (bool, string, error) { + c.mu.Lock() + pending := c.pending[accountID] + c.mu.Unlock() + if pending == nil { + return false, "", fmt.Errorf("login not started for account %s", accountID) + } + if time.Since(pending.createdAt) > loginPendingTTL { + c.mu.Lock() + delete(c.pending, accountID) + delete(c.pendingStates, pending.state) + c.mu.Unlock() + return false, "", fmt.Errorf("login expired; start again") + } + c.mu.Lock() + done, failed, message := pending.done, pending.failed, pending.message + credential := pending.credential + state := pending.state + c.mu.Unlock() + if failed { + return false, "", fmt.Errorf("%s", firstNonEmpty(message, "login failed")) + } + if !done { + return false, firstNonEmpty(message, "waiting for authorization"), nil + } + payload, err := credential.Encode() + if err != nil { + return false, "", err + } + if err := c.store.SaveCredentialPayload(ctx, accountID, CredentialFormat, payload); err != nil { + return false, "", err + } + _ = c.store.Observe(ctx, accountID, credential.AccountID, "ready", "", "") + c.mu.Lock() + delete(c.pending, accountID) + delete(c.pendingStates, state) + c.mu.Unlock() + return true, "login complete", nil +} + +// CompleteLogin handles a callback URL pasted by the user when the automatic +// loopback cannot reach this process. +func (c *Client) CompleteLogin(ctx context.Context, accountID, callbackURL string) error { + parsed, err := url.Parse(strings.TrimSpace(callbackURL)) + if err != nil { + return fmt.Errorf("parse callback url: %w", err) + } + query := parsed.Query() + code := query.Get("code") + if code == "" { + return fmt.Errorf("callback url missing code") + } + state := query.Get("state") + c.mu.Lock() + // Prefer the pending entry whose verifier minted this code: when the + // callback carries a state, the account slot may have been replaced by a + // newer login, so look the entry up by state instead of by accountID. + var pending *loginPending + pendingAccount := accountID + if state != "" { + if owner, ok := c.pendingStates[state]; ok { + pending = c.pending[owner] + pendingAccount = owner + } + } + if pending == nil { + pending = c.pending[accountID] + } + c.mu.Unlock() + verifier := "" + if pending != nil { + verifier = pending.codeVerifier + } + credential, err := c.exchangeCode(ctx, accountID, code, verifier) + if err != nil { + return err + } + return c.persistCredential(ctx, pendingAccount, credential, state) +} + +// ensureCallback binds the fixed loopback listener OpenAI's OAuth client +// redirects to. The port is part of the registered redirect_uri and cannot +// change; a second listener on it would fail, so it is created once. +func (c *Client) ensureCallback() error { + c.mu.Lock() + defer c.mu.Unlock() + if c.listener != nil { + return nil + } + ln, err := net.Listen("tcp", LoopbackAddr) + if err != nil { + return fmt.Errorf("codex callback listen %s: %w", LoopbackAddr, err) + } + c.listener = ln + auth.ServeLoopback(ln, pathCallback, "Codex", c.acceptCallback) + return nil +} + +func (c *Client) acceptCallback(ctx context.Context, rawURL string) error { + parsed, err := url.Parse(rawURL) + if err != nil { + return err + } + query := parsed.Query() + if errText := query.Get("error"); errText != "" { + desc := query.Get("error_description") + c.markPendingFailed(query.Get("state"), firstNonEmpty(desc, errText)) + return fmt.Errorf("%s", firstNonEmpty(desc, errText)) + } + code := query.Get("code") + state := query.Get("state") + if code == "" { + return fmt.Errorf("callback missing code") + } + c.mu.Lock() + accountID := c.pendingStates[state] + pending := c.pending[accountID] + c.mu.Unlock() + if pending == nil { + return fmt.Errorf("no pending login for state") + } + credential, err := c.exchangeCode(ctx, accountID, code, pending.codeVerifier) + if err != nil { + c.markPendingFailed(state, err.Error()) + return err + } + c.mu.Lock() + pending.credential = credential + pending.done = true + pending.message = "authorization received" + c.mu.Unlock() + return nil +} + +func (c *Client) markPendingFailed(state, message string) { + c.mu.Lock() + defer c.mu.Unlock() + if accountID, ok := c.pendingStates[state]; ok { + if pending := c.pending[accountID]; pending != nil { + pending.failed = true + pending.message = message + } + } +} + +func (c *Client) persistCredential(ctx context.Context, accountID string, credential Credential, state string) error { + payload, err := credential.Encode() + if err != nil { + return err + } + if err := c.store.SaveCredentialPayload(ctx, accountID, CredentialFormat, payload); err != nil { + return err + } + _ = c.store.Observe(ctx, accountID, credential.AccountID, "ready", "", "") + c.mu.Lock() + delete(c.pending, accountID) + if state != "" { + delete(c.pendingStates, state) + } + c.mu.Unlock() + return nil +} + +// exchangeCode swaps the authorization code for tokens at the token endpoint. +func (c *Client) exchangeCode(ctx context.Context, accountID, code, verifier string) (Credential, error) { + form := url.Values{ + "grant_type": {"authorization_code"}, + "client_id": {ClientID}, + "code": {code}, + "redirect_uri": {redirectURI}, + "code_verifier": {verifier}, + } + payload, status, err := c.do(ctx, accountID, http.MethodPost, TokenURL, []byte(form.Encode()), func(h http.Header) { + h.Set("Content-Type", "application/x-www-form-urlencoded") + h.Set("Accept", "application/json") + }) + if err != nil { + return Credential{}, err + } + if status != http.StatusOK { + return Credential{}, fmt.Errorf("token exchange failed with status %d: %s", status, strings.TrimSpace(string(payload))) + } + return parseTokenResponse(payload) +} + +// parseTokenResponse decodes the OAuth token endpoint response and pulls +// account_id/email out of the id_token JWT. +func parseTokenResponse(payload []byte) (Credential, error) { + var tok struct { + IDToken string `json:"id_token"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + ExpiresIn int64 `json:"expires_in"` + } + if err := json.Unmarshal(payload, &tok); err != nil { + return Credential{}, fmt.Errorf("token response parse: %w", err) + } + if tok.AccessToken == "" { + return Credential{}, fmt.Errorf("token response missing access_token") + } + credential := Credential{ + IDToken: tok.IDToken, + AccessToken: tok.AccessToken, + RefreshToken: tok.RefreshToken, + LastRefresh: time.Now().UTC().Format(time.RFC3339), + } + if tok.ExpiresIn > 0 { + credential.ExpiresAt = time.Now().Add(time.Duration(tok.ExpiresIn) * time.Second).Unix() + } + if claims := parseJWTClaims(tok.IDToken); claims != nil { + credential.AccountID = firstNonEmpty(claims.AccountID, claims.ChatGPTAccountID) + credential.Email = claims.Email + } + return credential, nil +} + +type jwtClaims struct { + AccountID string `json:"account_id"` + ChatGPTAccountID string `json:"chatgpt_account_id"` + Email string `json:"email"` +} + +func parseJWTClaims(token string) *jwtClaims { + parts := strings.Split(token, ".") + if len(parts) != 3 { + return nil + } + payload, err := base64.RawURLEncoding.DecodeString(parts[1]) + if err != nil { + return nil + } + var claims jwtClaims + // account_id can nest under https://api.openai.com/auth. + var raw map[string]json.RawMessage + if json.Unmarshal(payload, &raw) != nil { + return nil + } + _ = json.Unmarshal(payload, &claims) + if claims.AccountID == "" { + for key, value := range raw { + if !strings.HasSuffix(key, "auth") { + continue + } + var nested struct { + AccountID string `json:"account_id"` + } + if json.Unmarshal(value, &nested) == nil && nested.AccountID != "" { + claims.AccountID = nested.AccountID + } + } + } + return &claims +} + +// --------------------------------------------------------------------------- +// Token refresh +// --------------------------------------------------------------------------- + +// credential loads and refreshes the account credential when needed. +func (c *Client) credential(ctx context.Context, accountID string) (Credential, error) { + _, payload, err := c.store.LoadCredentialPayload(ctx, accountID) + if err != nil { + return Credential{}, err + } + credential, err := DecodeCredential(payload) + if err != nil { + return Credential{}, err + } + if !credential.needsRefresh(time.Now()) { + return credential, nil + } + return c.refreshCredential(ctx, accountID, credential) +} + +func (c *Client) refreshCredential(ctx context.Context, accountID string, credential Credential) (Credential, error) { + c.mu.Lock() + if call, ok := c.refresh[accountID]; ok { + c.mu.Unlock() + select { + case <-call.done: + return call.cred, call.err + case <-ctx.Done(): + return credential, ctx.Err() + } + } + call := &refreshCall{done: make(chan struct{})} + c.refresh[accountID] = call + c.mu.Unlock() + + refreshed, err := c.refreshTokens(ctx, accountID, credential) + if err == nil { + if encoded, encErr := refreshed.Encode(); encErr == nil { + _ = c.store.SaveCredentialPayload(ctx, accountID, CredentialFormat, encoded) + } + } else { + _ = c.store.Observe(ctx, accountID, credential.AccountID, "login_required", err.Error(), accounts.KindAuth) + } + call.cred, call.err = refreshed, err + close(call.done) + c.mu.Lock() + delete(c.refresh, accountID) + c.mu.Unlock() + return refreshed, err +} + +func (c *Client) refreshTokens(ctx context.Context, accountID string, credential Credential) (Credential, error) { + if strings.TrimSpace(credential.RefreshToken) == "" { + return credential, fmt.Errorf("no refresh_token; re-login required") + } + form := url.Values{ + "grant_type": {"refresh_token"}, + "client_id": {ClientID}, + "refresh_token": {credential.RefreshToken}, + "scope": {AuthScope}, + } + payload, status, err := c.do(ctx, accountID, http.MethodPost, TokenURL, []byte(form.Encode()), func(h http.Header) { + h.Set("Content-Type", "application/x-www-form-urlencoded") + h.Set("Accept", "application/json") + }) + if err != nil { + return credential, err + } + if status != http.StatusOK { + return credential, fmt.Errorf("token refresh failed with status %d: %s", status, strings.TrimSpace(string(payload))) + } + refreshed, err := parseTokenResponse(payload) + if err != nil { + return credential, err + } + // Preserve fields the refresh response may omit. + if refreshed.RefreshToken == "" { + refreshed.RefreshToken = credential.RefreshToken + } + if refreshed.AccountID == "" { + refreshed.AccountID = credential.AccountID + } + if refreshed.Email == "" { + refreshed.Email = credential.Email + } + return refreshed, nil +} + +// --------------------------------------------------------------------------- +// Chat +// --------------------------------------------------------------------------- + +func (c *Client) chatRequest(ctx context.Context, credential Credential, req translate.ChatRequest, accountID string) (*http.Request, providers.ResolvedChat, error) { + caps := capsFor(req.Model) + if len(caps.ReasoningOptions) == 0 { + caps.Reasoning = true + caps.ReasoningOptions = []string{"low", "medium", "high"} + } + body, resolved, err := buildBody(req, caps) + if err != nil { + return nil, providers.ResolvedChat{}, err + } + // A per-account prompt_cache_key keeps the upstream session cache warm and + // satisfies the codex backend's Session-Id expectation (CLIProxyAPI sends a + // session UUID; a stable account-scoped id is equivalent here because one + // account is one upstream identity). + sessionID := sessionIDFor(accountID) + if sessionID != "" { + var obj map[string]any + if json.Unmarshal(body, &obj) == nil { + obj["prompt_cache_key"] = sessionID + body, _ = json.Marshal(obj) + } + } + httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, ChatBase+pathResponses, bytes.NewReader(body)) + if err != nil { + return nil, providers.ResolvedChat{}, err + } + SetChatHeaders(httpReq.Header, credential, sessionID, true) + return httpReq, resolved, nil +} + +// sessionIDFor derives a deterministic UUID-shaped session id from the account +// id, matching the upstream's prompt_cache_key/Session-Id convention. +func sessionIDFor(accountID string) string { + sum := sha256.Sum256([]byte("cli2api:codex:" + accountID)) + hexSum := hex.EncodeToString(sum[:]) + return fmt.Sprintf("%s-%s-%s-%s-%s", hexSum[0:8], hexSum[8:12], hexSum[12:16], hexSum[16:20], hexSum[20:32]) +} + +func (c *Client) ChatNonStream(ctx context.Context, accountID string, req translate.ChatRequest) (providers.ChatOutcome, error) { + credential, err := c.credential(ctx, accountID) + if err != nil { + return providers.ChatOutcome{}, err + } + httpReq, resolved, err := c.chatRequest(ctx, credential, req, accountID) + if err != nil { + return providers.ChatOutcome{}, err + } + client, err := c.httpClient(ctx, accountID) + if err != nil { + return providers.ChatOutcome{}, err + } + client.Timeout = 0 + resp, err := client.Do(httpReq) + if err != nil { + return providers.ChatOutcome{}, err + } + defer resp.Body.Close() + c.observeQuotaHeaders(accountID, resp.Header) + if resp.StatusCode >= 300 { + body, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + return providers.ChatOutcome{}, classifiedError(resp.StatusCode, body) + } + outcome, err := aggregate(resp.Body, req.Model) + if err != nil { + return providers.ChatOutcome{}, err + } + outcome.ReasoningLevel = resolved.ReasoningLevel + return outcome, nil +} + +func (c *Client) ChatStream(ctx context.Context, accountID string, req translate.ChatRequest) (*http.Response, providers.ResolvedChat, error) { + credential, err := c.credential(ctx, accountID) + if err != nil { + return nil, providers.ResolvedChat{}, err + } + httpReq, resolved, err := c.chatRequest(ctx, credential, req, accountID) + if err != nil { + return nil, providers.ResolvedChat{}, err + } + client, err := c.httpClient(ctx, accountID) + if err != nil { + return nil, providers.ResolvedChat{}, err + } + client.Timeout = 0 + resp, err := client.Do(httpReq) + if err != nil { + return nil, providers.ResolvedChat{}, err + } + c.observeQuotaHeaders(accountID, resp.Header) + if resp.StatusCode >= 300 { + body, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + resp.Body.Close() + return nil, providers.ResolvedChat{}, classifiedError(resp.StatusCode, body) + } + stream, err := rewriteStream(resp.Body, req.Model) + if err != nil { + resp.Body.Close() + return nil, providers.ResolvedChat{}, err + } + resp.Body = &responseBody{Reader: stream.Reader, closer: resp.Body} + return resp, resolved, nil +} + +// ResponsesStream is the /v1/responses passthrough: the codex upstream already +// speaks the Responses protocol, so the gateway can relay the body verbatim. +// ChatStream still returns the translated chat-completions dialect for the +// other public endpoints. +func (c *Client) ResponsesStream(ctx context.Context, accountID string, req translate.ChatRequest) (*http.Response, providers.ResolvedChat, error) { + credential, err := c.credential(ctx, accountID) + if err != nil { + return nil, providers.ResolvedChat{}, err + } + httpReq, resolved, err := c.chatRequest(ctx, credential, req, accountID) + if err != nil { + return nil, providers.ResolvedChat{}, err + } + client, err := c.httpClient(ctx, accountID) + if err != nil { + return nil, providers.ResolvedChat{}, err + } + client.Timeout = 0 + resp, err := client.Do(httpReq) + if err != nil { + return nil, providers.ResolvedChat{}, err + } + c.observeQuotaHeaders(accountID, resp.Header) + if resp.StatusCode >= 300 { + body, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + resp.Body.Close() + return nil, providers.ResolvedChat{}, classifiedError(resp.StatusCode, body) + } + return resp, resolved, nil +} + +// --------------------------------------------------------------------------- +// Models / Probe / Quota +// --------------------------------------------------------------------------- + +func (c *Client) Models(ctx context.Context, accountID string) ([]providers.ModelInfo, error) { + return catalogModelInfos(), nil +} + +func (c *Client) Probe(ctx context.Context, accountID string) (providers.AccountHealth, error) { + credential, err := c.credential(ctx, accountID) + if err != nil { + return providers.AccountHealth{LastError: err.Error()}, nil + } + if !credential.Ready() { + return providers.AccountHealth{UID: credential.AccountID, LastError: "codex credential incomplete; re-login required"}, nil + } + return providers.AccountHealth{Ready: true, Hot: true, UID: firstNonEmpty(credential.Email, credential.AccountID)}, nil +} + +// observeQuotaHeaders snapshots the x-codex-* rate-limit headers every +// response carries, so the console can show the 5h/7d windows without a +// separate probe endpoint. +func (c *Client) observeQuotaHeaders(accountID string, header http.Header) { + info := quotaFromHeaders(header) + if info == nil { + return + } + c.mu.Lock() + if c.quotaCache == nil { + c.quotaCache = map[string]*providers.QuotaInfo{} + } + c.quotaCache[accountID] = info + c.mu.Unlock() +} + +func (c *Client) Quota(ctx context.Context, accountID string) (*providers.QuotaInfo, error) { + c.mu.Lock() + cached := c.quotaCache[accountID] + c.mu.Unlock() + if cached != nil { + return cached, nil + } + // No standalone usage endpoint: quota rides on chat response headers. Make a + // minimal request only when nothing is cached yet? The codex upstream has no + // cheap ping; report empty instead of burning a turn. + if _, err := c.credential(ctx, accountID); err != nil { + return nil, err + } + return &providers.QuotaInfo{ + Unit: QuotaUnit, + FetchedAt: time.Now().UTC().Format(time.RFC3339), + ProviderID: "codex", + }, nil +} + +func classifiedError(status int, body []byte) error { + return &providers.Error{ + Kind: Classify(status, string(body)).Kind, + Status: Classify(status, string(body)).Status, + Message: Classify(status, string(body)).Message, + } +} + +func (c *Client) Adapter() providers.Adapter { + return providers.Adapter{ + ID: "codex", + Credential: credentialCodec{}, + Login: c, + Chat: c, + Models: c, + Classifier: classifier{}, + ImportExport: importer{}, + Prober: c, + StreamFormat: providers.StreamFormatResponses, + NativeResponses: c, + } +} + +type credentialCodec struct{} + +func (credentialCodec) Validate(payload []byte) error { return ValidateCredential(payload) } + +type classifier struct{} + +func (classifier) Classify(status int, body string) providers.ClassifiedError { + return Classify(status, body) +} + +type importer struct{} + +func (importer) ValidateImport(payload []byte) error { return ValidateCredential(payload) } + +func (importer) Export(ctx context.Context, accountID string) (map[string]any, error) { + return nil, providers.ErrUnsupported +} + +// randomHex returns n random bytes as lowercase hex. +func randomHex(n int) string { + raw := make([]byte, n) + if _, err := rand.Read(raw); err != nil { + return fmt.Sprintf("%x", time.Now().UnixNano()) + } + return hex.EncodeToString(raw) +} diff --git a/internal/providers/codex/credential.go b/internal/providers/codex/credential.go new file mode 100644 index 00000000..bcc4bf6d --- /dev/null +++ b/internal/providers/codex/credential.go @@ -0,0 +1,144 @@ +// Package codex implements the OpenAI Codex (ChatGPT subscription) in-process +// provider. Protocol constants live only in this package. +// +// Ported from github.com/router-for-me/CLIProxyAPI (MIT). +package codex + +import ( + "encoding/json" + "fmt" + "strings" + "time" +) + +const ( + CredentialFormat = "codex-oauth-v1" + + // OAuth endpoints and the public client_id the official codex CLI uses. + AuthURL = "https://auth.openai.com/oauth/authorize" + TokenURL = "https://auth.openai.com/oauth/token" + ClientID = "app_EMoamEEZ73f0CkXaXp7hrann" + Scope = "openid email profile offline_access" + AuthScope = "openid profile email" + + // LoopbackAddr is the fixed redirect the OpenAI OAuth client registers. + // Unlike Trae's random-port loopback this port is part of the registered + // redirect_uri, so it cannot change. + LoopbackAddr = "127.0.0.1:1455" + pathCallback = "/auth/callback" + redirectURI = "http://localhost:1455/auth/callback" + + ChatBase = "https://chatgpt.com/backend-api/codex" + pathResponses = "/responses" + + // Cloaking: upstream gates on the official codex CLI UA/originator. + UserAgent = "codex-tui/0.154.0 (Mac OS 26.5.2; arm64) iTerm.app/3.6.11 (codex-tui; 0.154.0)" + Originator = "codex-tui" + + QuotaUnit = "rate_limit_window" +) + +const ( + refreshLead = 5 * time.Minute + loginPendingTTL = 10 * time.Minute +) + +// Credential is the canonical storage payload shape. Field names match the +// CodexTokenStorage JSON CLIProxyAPI writes so import/export round-trips. +type Credential struct { + IDToken string `json:"id_token,omitempty"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + AccountID string `json:"account_id"` + Email string `json:"email,omitempty"` + // ExpiresAt is a Unix second timestamp for the access token. + ExpiresAt int64 `json:"expires_at"` + LastRefresh string `json:"last_refresh,omitempty"` +} + +func DecodeCredential(payload []byte) (Credential, error) { + var flat Credential + if err := json.Unmarshal(payload, &flat); err == nil && + (flat.AccessToken != "" || flat.RefreshToken != "") { + flat.ExpiresAt = unixSeconds(flat.ExpiresAt) + return flat, nil + } + // Accept CLIProxyAPI's nested token_data shape on import. + var nested struct { + TokenData struct { + IDToken string `json:"id_token"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + AccountID string `json:"account_id"` + Email string `json:"email"` + Expire string `json:"expired"` + } `json:"token_data"` + LastRefresh string `json:"last_refresh"` + } + if err := json.Unmarshal(payload, &nested); err == nil && + (nested.TokenData.AccessToken != "" || nested.TokenData.RefreshToken != "") { + return Credential{ + IDToken: nested.TokenData.IDToken, + AccessToken: nested.TokenData.AccessToken, + RefreshToken: nested.TokenData.RefreshToken, + AccountID: nested.TokenData.AccountID, + Email: nested.TokenData.Email, + ExpiresAt: parseExpire(nested.TokenData.Expire), + LastRefresh: nested.LastRefresh, + }, nil + } + return Credential{}, fmt.Errorf("codex credential requires access_token or refresh_token") +} + +func (c Credential) Encode() ([]byte, error) { + return json.Marshal(c) +} + +func (c Credential) Ready() bool { + return strings.TrimSpace(c.RefreshToken) != "" && strings.TrimSpace(c.AccountID) != "" +} + +func ValidateCredential(payload []byte) error { + credential, err := DecodeCredential(payload) + if err != nil { + return err + } + if strings.TrimSpace(credential.RefreshToken) == "" && strings.TrimSpace(credential.AccessToken) == "" { + return fmt.Errorf("codex credential requires refresh_token or access_token") + } + return nil +} + +func (c Credential) needsRefresh(now time.Time) bool { + if strings.TrimSpace(c.AccessToken) == "" { + return true + } + if c.ExpiresAt <= 0 { + return true + } + return now.Add(refreshLead).Unix() >= c.ExpiresAt +} + +func unixSeconds(value int64) int64 { + if value > 1e12 { + return value / 1000 + } + return value +} + +// parseExpire accepts both Unix seconds and RFC3339-ish strings; CLIProxyAPI +// stores Expire as a string timestamp. +func parseExpire(raw string) int64 { + raw = strings.TrimSpace(raw) + if raw == "" { + return 0 + } + if t, err := time.Parse(time.RFC3339, raw); err == nil { + return t.Unix() + } + var n int64 + if _, err := fmt.Sscanf(raw, "%d", &n); err == nil { + return unixSeconds(n) + } + return 0 +} diff --git a/internal/providers/codex/headers.go b/internal/providers/codex/headers.go new file mode 100644 index 00000000..e32c472e --- /dev/null +++ b/internal/providers/codex/headers.go @@ -0,0 +1,27 @@ +package codex + +import "net/http" + +// SetChatHeaders applies the upstream headers the ChatGPT codex backend expects. +// Cloaking (codex-tui UA + Originator) is required: the upstream rejects generic +// clients with Cloudflare 1010 otherwise. +func SetChatHeaders(h http.Header, credential Credential, sessionID string, streaming bool) { + h.Set("Content-Type", "application/json") + if credential.AccessToken != "" { + h.Set("Authorization", "Bearer "+credential.AccessToken) + } + if credential.AccountID != "" { + h.Set("Chatgpt-Account-Id", credential.AccountID) + } + h.Set("Originator", Originator) + h.Set("User-Agent", UserAgent) + if streaming { + h.Set("Accept", "text/event-stream") + } else { + h.Set("Accept", "application/json") + } + h.Set("Connection", "Keep-Alive") + if sessionID != "" { + h.Set("Session-Id", sessionID) + } +} diff --git a/internal/providers/codex/models.json b/internal/providers/codex/models.json new file mode 100644 index 00000000..ce233bb7 --- /dev/null +++ b/internal/providers/codex/models.json @@ -0,0 +1,196 @@ +{ + "models": [ + { + "slug": "gpt-6-astra", + "display_name": "GPT-6-Astra", + "context_window": 272000, + "max_context_window": 872000, + "default_reasoning_level": "medium", + "supported_reasoning_levels": [ + "low", + "medium", + "high", + "xhigh", + "max", + "ultra" + ], + "input_modalities": [ + "text", + "image" + ], + "prefer_websockets": true, + "use_responses_lite": true, + "supported_in_api": true + }, + { + "slug": "gpt-6-sol", + "display_name": "GPT-6-Sol", + "context_window": 272000, + "max_context_window": 872000, + "default_reasoning_level": "medium", + "supported_reasoning_levels": [ + "low", + "medium", + "high", + "xhigh", + "max", + "ultra" + ], + "input_modalities": [ + "text", + "image" + ], + "prefer_websockets": true, + "use_responses_lite": true, + "supported_in_api": true + }, + { + "slug": "gpt-6-luna", + "display_name": "GPT-6-Luna", + "context_window": 272000, + "max_context_window": 872000, + "default_reasoning_level": "medium", + "supported_reasoning_levels": [ + "low", + "medium", + "high", + "xhigh", + "max" + ], + "input_modalities": [ + "text", + "image" + ], + "prefer_websockets": true, + "use_responses_lite": true, + "supported_in_api": true + }, + { + "slug": "gpt-reserve", + "display_name": "GPT-Reserve", + "context_window": 272000, + "max_context_window": 872000, + "default_reasoning_level": "medium", + "supported_reasoning_levels": [ + "low", + "medium", + "high", + "xhigh", + "max" + ], + "input_modalities": [ + "text", + "image" + ], + "prefer_websockets": true, + "use_responses_lite": true, + "supported_in_api": true + }, + { + "slug": "gpt-5.6-sol", + "display_name": "GPT-5.6-Sol", + "context_window": 272000, + "max_context_window": 872000, + "default_reasoning_level": "low", + "supported_reasoning_levels": [ + "low", + "medium", + "high", + "xhigh", + "max", + "ultra" + ], + "input_modalities": [ + "text", + "image" + ], + "prefer_websockets": true, + "use_responses_lite": true, + "supported_in_api": true + }, + { + "slug": "gpt-5.6-terra", + "display_name": "GPT-5.6-Terra", + "context_window": 272000, + "max_context_window": 872000, + "default_reasoning_level": "medium", + "supported_reasoning_levels": [ + "low", + "medium", + "high", + "xhigh", + "max", + "ultra" + ], + "input_modalities": [ + "text", + "image" + ], + "prefer_websockets": true, + "use_responses_lite": true, + "supported_in_api": true + }, + { + "slug": "gpt-5.6-luna", + "display_name": "GPT-5.6-Luna", + "context_window": 272000, + "max_context_window": 872000, + "default_reasoning_level": "medium", + "supported_reasoning_levels": [ + "low", + "medium", + "high", + "xhigh", + "max" + ], + "input_modalities": [ + "text", + "image" + ], + "prefer_websockets": true, + "use_responses_lite": true, + "supported_in_api": true + }, + { + "slug": "gpt-5.5", + "display_name": "GPT-5.5", + "context_window": 272000, + "max_context_window": 272000, + "default_reasoning_level": "medium", + "supported_reasoning_levels": [ + "low", + "medium", + "high", + "xhigh" + ], + "input_modalities": [ + "text", + "image" + ], + "prefer_websockets": true, + "use_responses_lite": false, + "supported_in_api": true + }, + { + "slug": "codex-auto-review", + "display_name": "Codex Auto Review", + "context_window": 272000, + "max_context_window": 872000, + "default_reasoning_level": "medium", + "supported_reasoning_levels": [ + "low", + "medium", + "high", + "xhigh", + "max" + ], + "input_modalities": [ + "text", + "image" + ], + "prefer_websockets": true, + "use_responses_lite": true, + "supported_in_api": true + } + ] +} diff --git a/internal/providers/codex/payload.go b/internal/providers/codex/payload.go new file mode 100644 index 00000000..88ce822d --- /dev/null +++ b/internal/providers/codex/payload.go @@ -0,0 +1,297 @@ +package codex + +import ( + "encoding/json" + + "github.com/caigee-cmd/cli2api/internal/providers" + "github.com/caigee-cmd/cli2api/internal/translate" +) + +// buildBody converts the provider-neutral ChatRequest into a codex Responses +// payload. Upstream is the ChatGPT backend Responses endpoint, so messages map +// to `input` items and most chat-completions fields carry over directly. +func buildBody(req translate.ChatRequest, caps providers.ModelCapabilities) ([]byte, providers.ResolvedChat, error) { + obj := map[string]any{ + "model": req.Model, + "stream": true, + // The codex backend requires instructions present; empty when the caller + // did not provide a system turn (mirrors CLIProxyAPI normalizeCodexInstructions). + "instructions": "", + } + + input, err := buildInput(req) + if err != nil { + return nil, providers.ResolvedChat{}, err + } + obj["input"] = input + + if len(req.Tools) > 0 { + var tools []json.RawMessage + if err := json.Unmarshal(req.Tools, &tools); err == nil && len(tools) > 0 { + obj["tools"] = normalizeTools(tools) + if req.ToolChoice != nil { + obj["tool_choice"] = normalizeToolChoice(req.ToolChoice) + } + // responses-lite models reject parallel tool calls. + if usesResponsesLite(req.Model) { + obj["parallel_tool_calls"] = false + } else if req.ParallelToolCalls != nil { + obj["parallel_tool_calls"] = *req.ParallelToolCalls + } + } + } + if _, hasTools := obj["tools"]; !hasTools { + delete(obj, "parallel_tool_calls") + } + + if len(req.MaxTokens) > 0 && string(req.MaxTokens) != "null" { + var n int + if json.Unmarshal(req.MaxTokens, &n) == nil && n > 0 { + obj["max_output_tokens"] = n + } + } + if len(req.Temperature) > 0 && string(req.Temperature) != "null" { + var t float64 + if json.Unmarshal(req.Temperature, &t) == nil { + obj["temperature"] = t + } + } + if len(req.TopP) > 0 && string(req.TopP) != "null" { + var p float64 + if json.Unmarshal(req.TopP, &p) == nil { + obj["top_p"] = p + } + } + if len(req.Stop) > 0 && string(req.Stop) != "null" { + obj["stop"] = req.Stop + } + if len(req.ResponseFormat) > 0 && string(req.ResponseFormat) != "null" { + obj["text"] = map[string]any{"format": req.ResponseFormat} + } + + resolved := providers.ResolvedChat{} + if level := resolveReasoning(req, caps); level != "" { + obj["reasoning"] = map[string]any{"effort": level} + resolved.ReasoningLevel = level + } + + body, err := json.Marshal(obj) + return body, resolved, err +} + +// resolveReasoning maps the client value through the shared clamp: catalog +// options win, unknown/empty falls back to the model default. +func resolveReasoning(req translate.ChatRequest, caps providers.ModelCapabilities) string { + requested := "" + if len(req.ReasoningEffort) > 0 { + var s string + if json.Unmarshal(req.ReasoningEffort, &s) == nil { + requested = s + } + } + return providers.ResolveReasoningLevel(requested, caps) +} + +// buildInput converts chat messages into Responses input items. +func buildInput(req translate.ChatRequest) ([]any, error) { + input := make([]any, 0, len(req.Messages)) + for _, msg := range req.Messages { + role := msg.Role + switch role { + case "system", "developer": + role = "developer" + } + item := map[string]any{ + "type": "message", + "role": role, + } + if msg.ToolCallID != "" { + // Tool result → function_call_output item. + input = append(input, map[string]any{ + "type": "function_call_output", + "call_id": msg.ToolCallID, + "output": translate.ContentToString(msg.Content), + }) + continue + } + content, err := responsesContent(msg) + if err != nil { + return nil, err + } + item["content"] = content + input = append(input, item) + if len(msg.ToolCalls) > 0 { + calls, err := functionCallItems(msg.ToolCalls) + if err != nil { + return nil, err + } + input = append(input, calls...) + } + } + return input, nil +} + +// responsesContent maps a chat message's content to Responses content parts. +func responsesContent(msg translate.ChatMessage) (any, error) { + switch content := msg.Content.(type) { + case string: + partType := "input_text" + if msg.Role == "assistant" { + partType = "output_text" + } + return []any{map[string]any{"type": partType, "text": content}}, nil + case []any: + parts := make([]any, 0, len(content)) + for _, raw := range content { + part, ok := raw.(map[string]any) + if !ok { + continue + } + typ, _ := part["type"].(string) + switch typ { + case "text": + partType := "input_text" + if msg.Role == "assistant" { + partType = "output_text" + } + parts = append(parts, map[string]any{"type": partType, "text": part["text"]}) + case "image_url": + parts = append(parts, map[string]any{"type": "input_image", "image_url": imageURLString(part["image_url"])}) + default: + return nil, errUnsupportedContent(typ) + } + } + return parts, nil + case nil: + return []any{}, nil + default: + return translate.ContentToString(content), nil + } +} + +func imageURLString(value any) string { + if s, ok := value.(string); ok { + return s + } + if m, ok := value.(map[string]any); ok { + if u, ok := m["url"].(string); ok { + return u + } + } + return "" +} + +func errUnsupportedContent(typ string) error { + return &providers.Error{Kind: "invalid_request", Status: 400, Message: "unsupported content type: " + typ} +} + +// functionCallItems converts OpenAI tool_calls on an assistant message into +// Responses function_call items. +func functionCallItems(raw json.RawMessage) ([]any, error) { + var calls []struct { + ID string `json:"id"` + Function struct { + Name string `json:"name"` + Arguments json.RawMessage `json:"arguments"` + } `json:"function"` + } + if err := json.Unmarshal(raw, &calls); err != nil { + return nil, err + } + items := make([]any, 0, len(calls)) + for _, call := range calls { + args := call.Function.Arguments + if len(args) == 0 { + args = json.RawMessage(`{}`) + } + // Responses expects arguments as a string. + var argStr string + if s, ok := rawJSONString(args); ok { + argStr = s + } else { + argStr = string(args) + } + items = append(items, map[string]any{ + "type": "function_call", + "call_id": call.ID, + "name": call.Function.Name, + "arguments": argStr, + }) + } + return items, nil +} + +// normalizeTools converts OpenAI function tools into Responses tool shape. +func normalizeTools(raw []json.RawMessage) []any { + out := make([]any, 0, len(raw)) + for _, item := range raw { + var tool map[string]json.RawMessage + if err := json.Unmarshal(item, &tool); err != nil { + continue + } + typ := rawMapString(tool, "type") + switch typ { + case "function": + var fn map[string]json.RawMessage + if err := json.Unmarshal(tool["function"], &fn); err != nil { + continue + } + out = append(out, map[string]any{ + "type": "function", + "name": rawMapString(fn, "name"), + "description": rawMapString(fn, "description"), + "parameters": rawMapJSONValue(fn, "parameters"), + }) + default: + // Already Responses-shaped or a hosted tool — pass through. + var passthrough map[string]any + if json.Unmarshal(item, &passthrough) == nil { + out = append(out, passthrough) + } + } + } + return out +} + +// normalizeToolChoice converts an OpenAI tool_choice to the Responses form. +func normalizeToolChoice(raw json.RawMessage) any { + var s string + if json.Unmarshal(raw, &s) == nil { + return s + } + var obj map[string]json.RawMessage + if json.Unmarshal(raw, &obj) != nil { + return nil + } + if rawMapString(obj, "type") == "function" { + var fn map[string]json.RawMessage + if json.Unmarshal(obj["function"], &fn) == nil { + return map[string]any{"type": "function", "name": rawMapString(fn, "name")} + } + } + return nil +} + +func rawMapString(source map[string]json.RawMessage, key string) string { + var s string + if json.Unmarshal(source[key], &s) != nil { + return "" + } + return s +} + +func rawMapJSONValue(source map[string]json.RawMessage, key string) json.RawMessage { + value := source[key] + if len(value) == 0 || string(value) == "null" { + return nil + } + return value +} + +func rawJSONString(raw json.RawMessage) (string, bool) { + var s string + if err := json.Unmarshal(raw, &s); err != nil { + return "", false + } + return s, true +} diff --git a/internal/providers/codex/pkce.go b/internal/providers/codex/pkce.go new file mode 100644 index 00000000..7e4a41f4 --- /dev/null +++ b/internal/providers/codex/pkce.go @@ -0,0 +1,34 @@ +package codex + +import ( + "crypto/rand" + "crypto/sha256" + "encoding/base64" + "errors" +) + +// pkceVerifier returns a fresh RFC 7636 code verifier. +func pkceVerifier() (string, error) { + raw := make([]byte, 32) + if _, err := rand.Read(raw); err != nil { + return "", err + } + return base64.RawURLEncoding.EncodeToString(raw), nil +} + +// pkceChallenge derives the S256 challenge for a verifier. +func pkceChallenge(verifier string) string { + sum := sha256.Sum256([]byte(verifier)) + return base64.RawURLEncoding.EncodeToString(sum[:]) +} + +func pkcePair() (verifier, challenge string, err error) { + verifier, err = pkceVerifier() + if err != nil { + return "", "", err + } + if verifier == "" { + return "", "", errors.New("empty pkce verifier") + } + return verifier, pkceChallenge(verifier), nil +} diff --git a/internal/providers/codex/quota.go b/internal/providers/codex/quota.go new file mode 100644 index 00000000..3d2296d0 --- /dev/null +++ b/internal/providers/codex/quota.go @@ -0,0 +1,83 @@ +package codex + +import ( + "net/http" + "strconv" + "strings" + "time" + + "github.com/caigee-cmd/cli2api/internal/providers" +) + +// quotaFromHeaders converts the x-codex-* rate-limit headers the codex backend +// attaches to every response into QuotaInfo windows. Header names observed: +// x-codex-primary-used-percent, x-codex-primary-reset-after-seconds (5h window), +// x-codex-secondary-used-percent, x-codex-secondary-reset-after-seconds (7d), +// plus x-codex-*-window-minutes variants and x-codex-plan-type. +func quotaFromHeaders(h http.Header) *providers.QuotaInfo { + primary := windowFromHeaders(h, "X-Codex-Primary-", "primary") + secondary := windowFromHeaders(h, "X-Codex-Secondary-", "secondary") + if primary == nil && secondary == nil { + return nil + } + windows := []providers.QuotaWindow{} + var usedPct float64 + exceeded := false + if primary != nil { + windows = append(windows, *primary) + usedPct = primary.Percentage + exceeded = exceeded || primary.Exceeded + } + if secondary != nil { + windows = append(windows, *secondary) + // Route on the tighter window. + if secondary.Percentage > usedPct { + usedPct = secondary.Percentage + } + exceeded = exceeded || secondary.Exceeded + } + return &providers.QuotaInfo{ + Used: usedPct, + Total: 100, + Remaining: 100 - usedPct, + Percentage: usedPct, + Unit: QuotaUnit, + Exceeded: exceeded, + FetchedAt: time.Now().UTC().Format(time.RFC3339), + Windows: windows, + ProviderID: "codex", + } +} + +func windowFromHeaders(h http.Header, prefix, label string) *providers.QuotaWindow { + used := headerFloat(h, prefix+"Used-Percent") + resetSecs := headerFloat(h, prefix+"Reset-After-Seconds") + windowMinutes := headerFloat(h, prefix+"Window-Minutes") + if used <= 0 && resetSecs <= 0 { + return nil + } + window := &providers.QuotaWindow{ + ID: label, + Label: label + " window", + Used: used, + Total: 100, + Remaining: 100 - used, + Percentage: used, + Unit: "percent", + Exceeded: used >= 100, + } + if resetSecs > 0 { + window.ResetAt = time.Now().Add(time.Duration(resetSecs) * time.Second).UTC().Format(time.RFC3339) + } + _ = windowMinutes + return window +} + +func headerFloat(h http.Header, name string) float64 { + raw := strings.TrimSpace(h.Get(name)) + if raw == "" { + return 0 + } + f, _ := strconv.ParseFloat(raw, 64) + return f +} diff --git a/internal/providers/codex/s04_interfaces_test.go b/internal/providers/codex/s04_interfaces_test.go new file mode 100644 index 00000000..9e621200 --- /dev/null +++ b/internal/providers/codex/s04_interfaces_test.go @@ -0,0 +1,249 @@ +package codex + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" + "time" + + "github.com/caigee-cmd/cli2api/internal/accounts" + "github.com/caigee-cmd/cli2api/internal/providers" + "github.com/caigee-cmd/cli2api/internal/translate" +) + +type testStore struct { + items map[string][]byte +} + +func (s testStore) Get(context.Context, string) (accounts.Account, error) { + return accounts.Account{Provider: "codex", ProviderRegion: "global"}, nil +} +func (s testStore) LoadCredentialPayload(_ context.Context, accountID string) (string, []byte, error) { + payload, ok := s.items[accountID] + if !ok { + return "", nil, accounts.ErrAccountNotFound + } + return CredentialFormat, payload, nil +} +func (testStore) SaveCredentialPayload(context.Context, string, string, []byte) error { return nil } +func (testStore) Observe(context.Context, string, string, string, string, string) error { + return nil +} + +func credentialPayload() []byte { + payload, _ := Credential{ + AccessToken: "at", + RefreshToken: "rt", + AccountID: "acct_123", + Email: "u@example.com", + ExpiresAt: time.Now().Add(time.Hour).Unix(), + }.Encode() + return payload +} + +func TestAdapterCapabilities(t *testing.T) { + adapter := NewClient(testStore{}).Adapter() + if adapter.ID != "codex" { + t.Fatalf("adapter id %q", adapter.ID) + } + for _, capability := range []string{"credential", "login", "chat", "models", "classifier", "import_export", "prober", "native_responses"} { + if !adapter.Supports(capability) { + t.Fatalf("missing capability %q", capability) + } + } + if adapter.Supports("checkin") { + t.Fatalf("codex must not support checkin") + } +} + +func TestCredentialRoundTrip(t *testing.T) { + cred := Credential{ + IDToken: "id", + AccessToken: "at", + RefreshToken: "rt", + AccountID: "acct", + Email: "u@example.com", + ExpiresAt: 1893456000, + } + payload, err := cred.Encode() + if err != nil { + t.Fatal(err) + } + if err := ValidateCredential(payload); err != nil { + t.Fatal(err) + } + decoded, err := DecodeCredential(payload) + if err != nil { + t.Fatal(err) + } + if decoded.AccessToken != "at" || decoded.AccountID != "acct" || !decoded.Ready() { + t.Fatalf("decoded %+v", decoded) + } +} + +func TestDecodeCredentialNestedTokenData(t *testing.T) { + payload := []byte(`{"token_data":{"access_token":"at","refresh_token":"rt","account_id":"acct","email":"e@x","expired":"2027-01-01T00:00:00Z"}}`) + cred, err := DecodeCredential(payload) + if err != nil { + t.Fatal(err) + } + if cred.AccessToken != "at" || cred.AccountID != "acct" || cred.ExpiresAt == 0 { + t.Fatalf("nested decode %+v", cred) + } +} + +func TestBuildBodyReasoningClamp(t *testing.T) { + caps := capsFor("gpt-5.5") + req := translate.ChatRequest{ + Model: "gpt-5.5", + Messages: []translate.ChatMessage{{Role: "user", Content: "hi"}}, + ReasoningEffort: json.RawMessage(`"max"`), + } + body, resolved, err := buildBody(req, caps) + if err != nil { + t.Fatal(err) + } + // gpt-5.5 declares low/medium/high/xhigh; "max" clamps to the default. + if resolved.ReasoningLevel != "medium" { + t.Fatalf("reasoning level %q", resolved.ReasoningLevel) + } + var obj map[string]any + if json.Unmarshal(body, &obj) != nil { + t.Fatal("body not json") + } + if obj["model"] != "gpt-5.5" || obj["stream"] != true || obj["instructions"] != "" { + t.Fatalf("body %v", obj) + } + reasoning, _ := obj["reasoning"].(map[string]any) + if reasoning["effort"] != "medium" { + t.Fatalf("reasoning %v", obj["reasoning"]) + } +} + +func TestBuildBodyToolCallItems(t *testing.T) { + req := translate.ChatRequest{ + Model: "gpt-5.5", + Messages: []translate.ChatMessage{ + {Role: "user", Content: "call it"}, + {Role: "assistant", Content: "", ToolCalls: json.RawMessage(`[{"id":"call_1","type":"function","function":{"name":"run","arguments":"{\"x\":1}"}}]`)}, + {Role: "tool", ToolCallID: "call_1", Content: "done"}, + }, + } + body, _, err := buildBody(req, capsFor("gpt-5.5")) + if err != nil { + t.Fatal(err) + } + var obj struct { + Input []map[string]any `json:"input"` + } + if json.Unmarshal(body, &obj) != nil { + t.Fatal("bad json") + } + if len(obj.Input) != 4 { + t.Fatalf("input items %d", len(obj.Input)) + } + if obj.Input[2]["type"] != "function_call" || obj.Input[3]["type"] != "function_call_output" { + t.Fatalf("input %v", obj.Input) + } +} + +func TestAggregateTerminal(t *testing.T) { + sse := strings.Join([]string{ + `event: response.output_text.delta`, + `data: {"type":"response.output_text.delta","delta":"hello"}`, + ``, + `event: response.output_text.delta`, + `data: {"type":"response.output_text.delta","delta":" world"}`, + ``, + `event: response.completed`, + `data: {"type":"response.completed","response":{"status":"completed","usage":{"input_tokens":10,"output_tokens":5},"output":[{"type":"message","content":[{"type":"output_text","text":"hello world"}]}]}}`, + ``, + }, "\n") + outcome, err := aggregate(strings.NewReader(sse), "gpt-5.5") + if err != nil { + t.Fatal(err) + } + if outcome.Content != "hello world" { + t.Fatalf("content %q", outcome.Content) + } + if outcome.PromptTokens != 10 || outcome.CompletionTokens != 5 { + t.Fatalf("usage %+v", outcome) + } +} + +func TestChatStreamRewritesToChatCompletions(t *testing.T) { + sse := strings.Join([]string{ + `event: response.output_text.delta`, + `data: {"type":"response.output_text.delta","delta":"hi"}`, + ``, + `event: response.completed`, + `data: {"type":"response.completed","response":{"status":"completed","usage":{"input_tokens":1,"output_tokens":1},"output":[]}}`, + ``, + }, "\n") + upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Header.Get("Chatgpt-Account-Id") != "acct_123" { + t.Errorf("missing account id header") + } + if r.Header.Get("Originator") != Originator { + t.Errorf("missing originator") + } + w.Header().Set("Content-Type", "text/event-stream") + w.Header().Set("X-Codex-Primary-Used-Percent", "42") + _, _ = w.Write([]byte(sse)) + })) + defer upstream.Close() + + client := NewClient(testStore{items: map[string][]byte{"a1": credentialPayload()}}) + // Point the chat base at the test server. + old := ChatBase + _ = old + resp, resolved, err := func() (*http.Response, providers.ResolvedChat, error) { + credential, err := client.credential(context.Background(), "a1") + if err != nil { + return nil, providers.ResolvedChat{}, err + } + req := translate.ChatRequest{Model: "gpt-5.5", Messages: []translate.ChatMessage{{Role: "user", Content: "hi"}}} + httpReq, resolved, err := client.chatRequest(context.Background(), credential, req, "a1") + if err != nil { + return nil, resolved, err + } + httpReq.URL.Host = strings.TrimPrefix(upstream.URL, "http://") + httpReq.URL.Scheme = "http" + httpReq.Host = httpReq.URL.Host + out, err := http.DefaultClient.Do(httpReq) + return out, resolved, err + }() + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + stream, err := rewriteStream(resp.Body, "gpt-5.5") + if err != nil { + t.Fatal(err) + } + buf := make([]byte, 8192) + n, _ := stream.Reader.Read(buf) + out := string(buf[:n]) + if !strings.Contains(out, `"content":"hi"`) { + t.Fatalf("expected content delta, got %s", out) + } + if !strings.Contains(out, "[DONE]") && !strings.Contains(out, "data:") { + t.Fatalf("expected SSE output, got %s", out) + } + _ = resolved +} + +func TestClassifyAuth(t *testing.T) { + if got := Classify(401, `{"error":{"code":"invalid_api_key","message":"bad"}}`); got.Kind != accounts.KindAuth { + t.Fatalf("kind %q", got.Kind) + } + if got := Classify(429, `{"error":{"code":"rate_limit_exceeded","message":"slow"}}`); got.Kind != accounts.KindRateLimit { + t.Fatalf("kind %q", got.Kind) + } + if got := Classify(403, `cloudflare`); got.Kind != accounts.KindUnavailable { + t.Fatalf("cloudflare kind %q", got.Kind) + } +} diff --git a/internal/providers/codex/sse.go b/internal/providers/codex/sse.go new file mode 100644 index 00000000..994fc2bf --- /dev/null +++ b/internal/providers/codex/sse.go @@ -0,0 +1,453 @@ +package codex + +import ( + "bufio" + "encoding/json" + "fmt" + "io" + "strings" + "time" + + "github.com/caigee-cmd/cli2api/internal/providers" +) + +const maxSSELineSize = 4 << 20 + +// rewriteStream wraps the upstream Responses SSE body and emits an OpenAI +// chat-completions delta stream (`choices[].delta`) that the gateway relay +// consumes. Terminal event is data: [DONE]. +func rewriteStream(body io.Reader, model string) (*streamResult, error) { + pr, pw := io.Pipe() + state := &streamConverter{model: model, writer: pw} + go state.run(body) + return &streamResult{Reader: pr}, nil +} + +type streamResult struct { + Reader io.Reader +} + +func (s *streamResult) Close() error { + if closer, ok := s.Reader.(io.Closer); ok { + return closer.Close() + } + return nil +} + +// streamConverter translates codex Responses SSE events into chat-completions +// chunks line by line. +type streamConverter struct { + model string + writer *io.PipeWriter + + // per-turn state + textStarted bool + reasoningText strings.Builder + reasoningDone bool + toolCalls map[int]*pendingCall + toolOrder []int + finishReason string + promptTokens int + completionTokens int + sawTerminal bool +} + +type pendingCall struct { + id string + name string + arguments strings.Builder + announced bool + index int +} + +func (c *streamConverter) run(body io.Reader) { + defer c.writer.Close() + scanner := bufio.NewScanner(body) + scanner.Buffer(make([]byte, 0, 64*1024), maxSSELineSize) + var eventName, data strings.Builder + flush := func() { + event := strings.TrimSpace(eventName.String()) + payload := strings.TrimSpace(data.String()) + eventName.Reset() + data.Reset() + if payload == "" { + return + } + c.handleEvent(event, payload) + } + for scanner.Scan() { + line := strings.TrimSuffix(scanner.Text(), "\r") + if line == "" { + flush() + continue + } + if strings.HasPrefix(line, "event:") { + if eventName.Len() > 0 { + eventName.WriteString(" ") + } + eventName.WriteString(strings.TrimSpace(strings.TrimPrefix(line, "event:"))) + } else if strings.HasPrefix(line, "data:") { + if data.Len() > 0 { + data.WriteString("\n") + } + data.WriteString(strings.TrimPrefix(line, "data:")) + } + } + flush() + if !c.sawTerminal { + c.emitDone() + } +} + +func (c *streamConverter) handleEvent(event, payload string) { + var obj map[string]json.RawMessage + if json.Unmarshal([]byte(payload), &obj) != nil { + return + } + typ := event + if t := rawMapString(obj, "type"); t != "" { + typ = t + } + switch typ { + case "response.output_text.delta": + var delta struct { + Delta string `json:"delta"` + } + if json.Unmarshal(obj["delta"], &delta.Delta) != nil { + // delta is a plain string in the payload. + } + var d string + if json.Unmarshal(obj["delta"], &d) == nil { + c.emitContent(d) + } + case "response.reasoning_summary_text.delta", "response.reasoning_text.delta": + var d string + if json.Unmarshal(obj["delta"], &d) == nil { + c.emitReasoning(d) + } + case "response.output_item.added", "response.output_item.done": + var item struct { + Type string `json:"type"` + Status string `json:"status"` + } + if json.Unmarshal(obj["item"], &item) != nil { + return + } + case "response.function_call_arguments.delta": + var delta struct { + Delta string `json:"delta"` + ItemID string `json:"item_id"` + OutputIndex int `json:"output_index"` + } + if json.Unmarshal([]byte(payload), &delta) == nil { + c.emitToolArgDelta(delta.OutputIndex, delta.ItemID, delta.Delta) + } + case "response.function_call_arguments.done", "response.custom_tool_call_input.done": + var done struct { + OutputIndex int `json:"output_index"` + ItemID string `json:"item_id"` + Name string `json:"name"` + CallID string `json:"call_id"` + Arguments string `json:"arguments"` + Input string `json:"input"` + } + if json.Unmarshal([]byte(payload), &done) == nil { + c.emitToolDone(done.OutputIndex, done.ItemID, done.CallID, done.Name, firstNonEmpty(done.Arguments, done.Input)) + } + case "response.completed", "response.incomplete": + var resp struct { + Response struct { + Status string `json:"status"` + Usage struct { + InputTokens int `json:"input_tokens"` + OutputTokens int `json:"output_tokens"` + } `json:"usage"` + Output []json.RawMessage `json:"output"` + } `json:"response"` + } + if json.Unmarshal([]byte(payload), &resp) == nil { + c.promptTokens = resp.Response.Usage.InputTokens + c.completionTokens = resp.Response.Usage.OutputTokens + c.finishReason = "stop" + if typ == "response.incomplete" { + c.finishReason = "length" + } + c.sawTerminal = true + c.emitUsage() + c.emitFinish() + } + case "response.failed", "error": + var errObj struct { + Message string `json:"message"` + Code string `json:"code"` + } + _ = json.Unmarshal([]byte(payload), &errObj) + c.emitDone() + c.sawTerminal = true + case "response.created": + // no-op; gateway synthesizes its own response.created + } +} + +func (c *streamConverter) emitContent(text string) { + if text == "" { + return + } + c.textStarted = true + c.writeChunk(map[string]any{ + "choices": []any{map[string]any{ + "index": 0, + "delta": map[string]any{"content": text}, + }}, + }) +} + +func (c *streamConverter) emitReasoning(text string) { + if text == "" { + return + } + c.reasoningText.WriteString(text) + c.writeChunk(map[string]any{ + "choices": []any{map[string]any{ + "index": 0, + "delta": map[string]any{"reasoning_content": text}, + }}, + }) +} + +func (c *streamConverter) toolCall(outputIndex int, itemID string) *pendingCall { + if c.toolCalls == nil { + c.toolCalls = map[int]*pendingCall{} + } + call, ok := c.toolCalls[outputIndex] + if !ok { + call = &pendingCall{index: len(c.toolOrder)} + c.toolCalls[outputIndex] = call + c.toolOrder = append(c.toolOrder, outputIndex) + } + if itemID != "" && call.id == "" { + call.id = itemID + } + return call +} + +func (c *streamConverter) emitToolArgDelta(outputIndex int, itemID, delta string) { + call := c.toolCall(outputIndex, itemID) + call.arguments.WriteString(delta) + if !call.announced { + return + } + c.writeChunk(map[string]any{ + "choices": []any{map[string]any{ + "index": 0, + "delta": map[string]any{ + "tool_calls": []any{map[string]any{ + "index": call.index, + "function": map[string]any{"arguments": delta}, + }}, + }, + }}, + }) +} + +func (c *streamConverter) emitToolDone(outputIndex int, itemID, callID, name, arguments string) { + call := c.toolCall(outputIndex, itemID) + if callID != "" { + call.id = callID + } + if name != "" { + call.name = name + } + if arguments != "" && call.arguments.Len() == 0 { + call.arguments.WriteString(arguments) + } + if call.announced { + return + } + call.announced = true + c.writeChunk(map[string]any{ + "choices": []any{map[string]any{ + "index": 0, + "delta": map[string]any{ + "tool_calls": []any{map[string]any{ + "index": call.index, + "id": firstNonEmpty(call.id, fmt.Sprintf("call_%d", call.index)), + "type": "function", + "function": map[string]any{ + "name": call.name, + "arguments": call.arguments.String(), + }, + }}, + }, + }}, + }) +} + +func (c *streamConverter) emitUsage() { + if c.promptTokens == 0 && c.completionTokens == 0 { + return + } + c.writeChunk(map[string]any{ + "usage": map[string]any{ + "prompt_tokens": c.promptTokens, + "completion_tokens": c.completionTokens, + "total_tokens": c.promptTokens + c.completionTokens, + }, + }) +} + +func (c *streamConverter) emitFinish() { + c.writeChunk(map[string]any{ + "choices": []any{map[string]any{ + "index": 0, + "delta": map[string]any{}, + "finish_reason": firstNonEmpty(c.finishReason, "stop"), + }}, + }) + c.emitDone() +} + +func (c *streamConverter) emitDone() { + _, _ = c.writer.Write([]byte("data: [DONE]\n\n")) +} + +func (c *streamConverter) writeChunk(obj map[string]any) { + obj["object"] = "chat.completion.chunk" + obj["model"] = c.model + obj["created"] = time.Now().Unix() + obj["id"] = "chatcmpl-codex" + payload, err := json.Marshal(obj) + if err != nil { + return + } + _, _ = c.writer.Write([]byte("data: " + string(payload) + "\n\n")) +} + +// aggregate reads a full upstream Responses SSE body and returns the final +// ChatOutcome, used for non-stream requests. +func aggregate(body io.Reader, model string) (providers.ChatOutcome, error) { + outcome := providers.ChatOutcome{Model: model, FinishReason: "stop", UsageSource: "upstream"} + var content strings.Builder + var reasoning strings.Builder + var toolCalls []json.RawMessage + sawTerminal := false + + scanner := bufio.NewScanner(body) + scanner.Buffer(make([]byte, 0, 64*1024), maxSSELineSize) + var eventData strings.Builder + flush := func() { + payload := strings.TrimSpace(eventData.String()) + eventData.Reset() + if payload == "" { + return + } + var obj map[string]json.RawMessage + if json.Unmarshal([]byte(payload), &obj) != nil { + return + } + switch rawMapString(obj, "type") { + case "response.output_text.delta": + var d string + if json.Unmarshal(obj["delta"], &d) == nil { + content.WriteString(d) + } + case "response.reasoning_summary_text.delta", "response.reasoning_text.delta": + var d string + if json.Unmarshal(obj["delta"], &d) == nil { + reasoning.WriteString(d) + } + case "response.completed", "response.incomplete": + var resp struct { + Response struct { + Status string `json:"status"` + Usage struct { + InputTokens int `json:"input_tokens"` + OutputTokens int `json:"output_tokens"` + } `json:"usage"` + Output []json.RawMessage `json:"output"` + } `json:"response"` + } + if json.Unmarshal([]byte(payload), &resp) == nil { + outcome.PromptTokens = resp.Response.Usage.InputTokens + outcome.CompletionTokens = resp.Response.Usage.OutputTokens + if rawMapString(obj, "type") == "response.incomplete" { + outcome.FinishReason = "length" + } + // Extract tool calls from completed output items. + for _, item := range resp.Response.Output { + var parsed struct { + Type string `json:"type"` + CallID string `json:"call_id"` + Name string `json:"name"` + Arguments string `json:"arguments"` + } + if json.Unmarshal(item, &parsed) != nil || parsed.Type != "function_call" { + continue + } + encoded, _ := json.Marshal(map[string]any{ + "id": parsed.CallID, + "type": "function", + "function": map[string]any{ + "name": parsed.Name, + "arguments": parsed.Arguments, + }, + }) + toolCalls = append(toolCalls, encoded) + } + sawTerminal = true + } + } + } + for scanner.Scan() { + line := strings.TrimSuffix(scanner.Text(), "\r") + if line == "" { + flush() + continue + } + if strings.HasPrefix(line, "data:") { + if eventData.Len() > 0 { + eventData.WriteString("\n") + } + eventData.WriteString(strings.TrimPrefix(line, "data:")) + } + } + flush() + if err := scanner.Err(); err != nil { + return outcome, err + } + if !sawTerminal { + return outcome, fmt.Errorf("codex stream ended without terminal event") + } + outcome.Content = content.String() + outcome.Reasoning = reasoning.String() + if len(toolCalls) > 0 { + outcome.ToolCalls = json.RawMessage("[" + strings.Join(rawMessages(toolCalls), ",") + "]") + outcome.FinishReason = "tool_calls" + } + return outcome, nil +} + +func rawMessages(items []json.RawMessage) []string { + out := make([]string, 0, len(items)) + for _, item := range items { + out = append(out, string(item)) + } + return out +} + +func firstNonEmpty(vals ...string) string { + for _, v := range vals { + if strings.TrimSpace(v) != "" { + return v + } + } + return "" +} + +// responseBody returns a synthetic *http.Response wrapping the rewritten stream. +type responseBody struct { + io.Reader + closer io.Closer +} + +func (r *responseBody) Close() error { return r.closer.Close() } diff --git a/internal/providers/interfaces.go b/internal/providers/interfaces.go index 2fffbcf3..cfcd6687 100644 --- a/internal/providers/interfaces.go +++ b/internal/providers/interfaces.go @@ -105,6 +105,21 @@ type ProviderChat interface { ChatStream(ctx context.Context, accountID string, req translate.ChatRequest) (*http.Response, ResolvedChat, error) } +// StreamFormatNames the SSE dialect a ProviderChat.ChatStream body speaks. +// Empty means OpenAI chat-completions deltas (the shared internal contract); +// "responses" means the upstream already emits OpenAI Responses events and the +// /v1/responses endpoint can relay them without translation. +const StreamFormatResponses = "responses" + +// NativeResponsesStreamer is an optional fast path: when a provider's upstream +// already speaks the OpenAI Responses protocol, the /v1/responses endpoint can +// relay the upstream body verbatim instead of translating through the shared +// chat-completions dialect. Providers that do not implement it fall back to +// ChatStream + translation. +type NativeResponsesStreamer interface { + ResponsesStream(ctx context.Context, accountID string, req translate.ChatRequest) (*http.Response, ResolvedChat, error) +} + // ModelCatalogProvider lists models an account can currently serve. type ModelCatalogProvider interface { Models(ctx context.Context, accountID string) ([]ModelInfo, error) @@ -225,6 +240,12 @@ type Adapter struct { ImportExport ImportExporter Prober AccountProber Checkin AccountCheckiner + // StreamFormat declares the SSE dialect ChatStream returns (see + // StreamFormat* constants). Empty means chat-completions deltas. + StreamFormat string + // NativeResponses is the optional /v1/responses passthrough. When set, the + // gateway prefers it over ChatStream+translation for responses requests. + NativeResponses NativeResponsesStreamer } func (a Adapter) Supports(capability string) bool { @@ -245,6 +266,8 @@ func (a Adapter) Supports(capability string) bool { return a.Prober != nil case "checkin": return a.Checkin != nil + case "native_responses": + return a.NativeResponses != nil default: return false } diff --git a/internal/providers/registry.go b/internal/providers/registry.go index b3530df5..40dfb893 100644 --- a/internal/providers/registry.go +++ b/internal/providers/registry.go @@ -216,12 +216,36 @@ var Command = ProviderDescriptor{ DefaultRegion: "global", } +// Codex descriptor. OpenAI Codex (ChatGPT subscription) via the ChatGPT +// backend Responses endpoint; OAuth with a fixed loopback redirect. +var Codex = ProviderDescriptor{ + ID: "codex", + Label: "Codex", + Runtime: RuntimeInProcess, + AuthTypes: []AuthType{AuthOAuth}, + CredentialFormats: []string{"codex-oauth-v1"}, + Capabilities: ProviderCapabilities{ + Chat: true, Stream: true, Tools: true, Images: true, Reasoning: true, + ModelCatalog: true, Usage: true, Login: true, BrowserLogin: true, + PATLogin: false, ImportExport: true, + }, + Regions: []RegionDescriptor{ + { + ID: "global", Label: "Global", ChatBase: "https://chatgpt.com/backend-api/codex", + AuthBase: "https://auth.openai.com", BillingBase: "https://chatgpt.com", + DefaultDomain: "chatgpt.com", + }, + }, + DefaultRegion: "global", +} + var registry = map[string]ProviderDescriptor{ Qoder.ID: Qoder, WorkBuddy.ID: WorkBuddy, Trae.ID: Trae, Devin.ID: Devin, Command.ID: Command, + Codex.ID: Codex, } func Get(id string) (ProviderDescriptor, bool) { diff --git a/internal/webui/static/assets/TrafficChart-6OfHAVPl.js b/internal/webui/static/assets/TrafficChart-C6BPz1n1.js similarity index 99% rename from internal/webui/static/assets/TrafficChart-6OfHAVPl.js rename to internal/webui/static/assets/TrafficChart-C6BPz1n1.js index 3d69ca53..b3905dd1 100644 --- a/internal/webui/static/assets/TrafficChart-6OfHAVPl.js +++ b/internal/webui/static/assets/TrafficChart-C6BPz1n1.js @@ -1,4 +1,4 @@ -import{a as e,c as t,d as n,i as r,l as i,n as a,o,r as s,s as c,t as l,u}from"./index-C4p-2Dwo.js";var d=`dangerouslySetInnerHTML.onCopy.onCopyCapture.onCut.onCutCapture.onPaste.onPasteCapture.onCompositionEnd.onCompositionEndCapture.onCompositionStart.onCompositionStartCapture.onCompositionUpdate.onCompositionUpdateCapture.onFocus.onFocusCapture.onBlur.onBlurCapture.onChange.onChangeCapture.onBeforeInput.onBeforeInputCapture.onInput.onInputCapture.onReset.onResetCapture.onSubmit.onSubmitCapture.onInvalid.onInvalidCapture.onLoad.onLoadCapture.onError.onErrorCapture.onKeyDown.onKeyDownCapture.onKeyPress.onKeyPressCapture.onKeyUp.onKeyUpCapture.onAbort.onAbortCapture.onCanPlay.onCanPlayCapture.onCanPlayThrough.onCanPlayThroughCapture.onDurationChange.onDurationChangeCapture.onEmptied.onEmptiedCapture.onEncrypted.onEncryptedCapture.onEnded.onEndedCapture.onLoadedData.onLoadedDataCapture.onLoadedMetadata.onLoadedMetadataCapture.onLoadStart.onLoadStartCapture.onPause.onPauseCapture.onPlay.onPlayCapture.onPlaying.onPlayingCapture.onProgress.onProgressCapture.onRateChange.onRateChangeCapture.onSeeked.onSeekedCapture.onSeeking.onSeekingCapture.onStalled.onStalledCapture.onSuspend.onSuspendCapture.onTimeUpdate.onTimeUpdateCapture.onVolumeChange.onVolumeChangeCapture.onWaiting.onWaitingCapture.onAuxClick.onAuxClickCapture.onClick.onClickCapture.onContextMenu.onContextMenuCapture.onDoubleClick.onDoubleClickCapture.onDrag.onDragCapture.onDragEnd.onDragEndCapture.onDragEnter.onDragEnterCapture.onDragExit.onDragExitCapture.onDragLeave.onDragLeaveCapture.onDragOver.onDragOverCapture.onDragStart.onDragStartCapture.onDrop.onDropCapture.onMouseDown.onMouseDownCapture.onMouseEnter.onMouseLeave.onMouseMove.onMouseMoveCapture.onMouseOut.onMouseOutCapture.onMouseOver.onMouseOverCapture.onMouseUp.onMouseUpCapture.onSelect.onSelectCapture.onTouchCancel.onTouchCancelCapture.onTouchEnd.onTouchEndCapture.onTouchMove.onTouchMoveCapture.onTouchStart.onTouchStartCapture.onPointerDown.onPointerDownCapture.onPointerMove.onPointerMoveCapture.onPointerUp.onPointerUpCapture.onPointerCancel.onPointerCancelCapture.onPointerEnter.onPointerEnterCapture.onPointerLeave.onPointerLeaveCapture.onPointerOver.onPointerOverCapture.onPointerOut.onPointerOutCapture.onGotPointerCapture.onGotPointerCaptureCapture.onLostPointerCapture.onLostPointerCaptureCapture.onScroll.onScrollCapture.onWheel.onWheelCapture.onAnimationStart.onAnimationStartCapture.onAnimationEnd.onAnimationEndCapture.onAnimationIteration.onAnimationIterationCapture.onTransitionEnd.onTransitionEndCapture`.split(`.`);function f(e){return typeof e==`string`&&d.includes(e)}var p=n(t()),m=new Set(`aria-activedescendant.aria-atomic.aria-autocomplete.aria-busy.aria-checked.aria-colcount.aria-colindex.aria-colspan.aria-controls.aria-current.aria-describedby.aria-details.aria-disabled.aria-errormessage.aria-expanded.aria-flowto.aria-haspopup.aria-hidden.aria-invalid.aria-keyshortcuts.aria-label.aria-labelledby.aria-level.aria-live.aria-modal.aria-multiline.aria-multiselectable.aria-orientation.aria-owns.aria-placeholder.aria-posinset.aria-pressed.aria-readonly.aria-relevant.aria-required.aria-roledescription.aria-rowcount.aria-rowindex.aria-rowspan.aria-selected.aria-setsize.aria-sort.aria-valuemax.aria-valuemin.aria-valuenow.aria-valuetext.className.color.height.id.lang.max.media.method.min.name.style.target.width.role.tabIndex.accentHeight.accumulate.additive.alignmentBaseline.allowReorder.alphabetic.amplitude.arabicForm.ascent.attributeName.attributeType.autoReverse.azimuth.baseFrequency.baselineShift.baseProfile.bbox.begin.bias.by.calcMode.capHeight.clip.clipPath.clipPathUnits.clipRule.colorInterpolation.colorInterpolationFilters.colorProfile.colorRendering.contentScriptType.contentStyleType.cursor.cx.cy.d.decelerate.descent.diffuseConstant.direction.display.divisor.dominantBaseline.dur.dx.dy.edgeMode.elevation.enableBackground.end.exponent.externalResourcesRequired.fill.fillOpacity.fillRule.filter.filterRes.filterUnits.floodColor.floodOpacity.focusable.fontFamily.fontSize.fontSizeAdjust.fontStretch.fontStyle.fontVariant.fontWeight.format.from.fx.fy.g1.g2.glyphName.glyphOrientationHorizontal.glyphOrientationVertical.glyphRef.gradientTransform.gradientUnits.hanging.horizAdvX.horizOriginX.href.ideographic.imageRendering.in2.in.intercept.k1.k2.k3.k4.k.kernelMatrix.kernelUnitLength.kerning.keyPoints.keySplines.keyTimes.lengthAdjust.letterSpacing.lightingColor.limitingConeAngle.local.markerEnd.markerHeight.markerMid.markerStart.markerUnits.markerWidth.mask.maskContentUnits.maskUnits.mathematical.mode.numOctaves.offset.opacity.operator.order.orient.orientation.origin.overflow.overlinePosition.overlineThickness.paintOrder.panose1.pathLength.patternContentUnits.patternTransform.patternUnits.pointerEvents.pointsAtX.pointsAtY.pointsAtZ.preserveAlpha.preserveAspectRatio.primitiveUnits.r.radius.refX.refY.renderingIntent.repeatCount.repeatDur.requiredExtensions.requiredFeatures.restart.result.rotate.rx.ry.seed.shapeRendering.slope.spacing.specularConstant.specularExponent.speed.spreadMethod.startOffset.stdDeviation.stemh.stemv.stitchTiles.stopColor.stopOpacity.strikethroughPosition.strikethroughThickness.string.stroke.strokeDasharray.strokeDashoffset.strokeLinecap.strokeLinejoin.strokeMiterlimit.strokeOpacity.strokeWidth.surfaceScale.systemLanguage.tableValues.targetX.targetY.textAnchor.textDecoration.textLength.textRendering.to.transform.u1.u2.underlinePosition.underlineThickness.unicode.unicodeBidi.unicodeRange.unitsPerEm.vAlphabetic.values.vectorEffect.version.vertAdvY.vertOriginX.vertOriginY.vHanging.vIdeographic.viewTarget.visibility.vMathematical.widths.wordSpacing.writingMode.x1.x2.x.xChannelSelector.xHeight.xlinkActuate.xlinkArcrole.xlinkHref.xlinkRole.xlinkShow.xlinkTitle.xlinkType.xmlBase.xmlLang.xmlns.xmlnsXlink.xmlSpace.y1.y2.y.yChannelSelector.z.zoomAndPan.ref.key.angle`.split(`.`));function h(e){return typeof e==`string`&&m.has(e)}function g(e){return typeof e==`string`&&e.startsWith(`data-`)}function _(e){if(typeof e!=`object`||!e)return{};var t={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(h(n)||g(n))&&(t[n]=e[n]);return t}function v(e){if(e==null)return null;if((0,p.isValidElement)(e)&&typeof e.props==`object`&&e.props!==null){var t=e.props;return _(t)}return typeof e==`object`&&!Array.isArray(e)?_(e):null}function y(e){var t={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(h(n)||g(n)||f(n))&&(t[n]=e[n]);return t}function b(e){return e==null?null:(0,p.isValidElement)(e)?y(e.props):typeof e==`object`&&!Array.isArray(e)?y(e):null}var x=[`children`,`width`,`height`,`viewBox`,`className`,`style`,`title`,`desc`];function S(){return S=Object.assign?Object.assign.bind():function(e){for(var t=1;t{var n=e.children,r=e.width,i=e.height,a=e.viewBox,s=e.className,c=e.style,l=e.title,u=e.desc,d=C(e,x),f=a||{width:r,height:i,x:0,y:0},m=o(`recharts-surface`,s);return p.createElement(`svg`,S({},y(d),{className:m,width:r,height:i,style:c,viewBox:`${f.x} ${f.y} ${f.width} ${f.height}`,ref:t}),p.createElement(`title`,null,l),p.createElement(`desc`,null,u),n)}),E=[`children`,`className`];function D(){return D=Object.assign?Object.assign.bind():function(e){for(var t=1;t{var n=e.children,r=e.className,i=O(e,E),a=o(`recharts-layer`,r);return p.createElement(`g`,D({className:a},y(i),{ref:t}),n)});function j(e){return e===`__proto__`}var M=/\.|(\[(?:[^[\]]*|(["'])(?:(?!\2)[^\\]|\\.)*?\2)\])/;function N(e){switch(typeof e){case`number`:case`symbol`:return!1;case`string`:return e===``||e.startsWith(`.`)||e.endsWith(`.`)?!1:M.test(e);default:return!1}}function ee(e){return typeof e==`string`||typeof e==`symbol`?e:Object.is(e?.valueOf?.(),-0)?`-0`:String(e)}function te(e){return typeof e==`symbol`||e instanceof Symbol}function ne(e){return e==null?``:re(e)}function re(e){if(typeof e==`string`)return e;if(Array.isArray(e))return e.map(re).join(`,`);if(te(e))return e.toString();let t=e+``;return t===`0`&&Object.is(Number(e),-0)?`-0`:t}function ie(e){if(Array.isArray(e))return e.map(ee);if(typeof e==`symbol`)return[e];e=ne(e);let t=[],n=e.length;if(n===0)return t;let r=0,i=``,a=``,o=!1,s=!1,c=/^-?\d+(?:\.\d+)?$/;for(e.charCodeAt(0)===46&&t.push(``);r1&&arguments[1]!==void 0?arguments[1]:se),n=Math.round(e*t)/t;return Object.is(n,-0)?0:n}function P(e){var t=[...arguments].slice(1);return e.reduce((e,n,r)=>{var i=t[r-1];return typeof i==`string`?e+i+n:i===void 0?e+n:e+ce(i)+n},``)}var le=e=>e===0?0:e>0?1:-1,ue=e=>typeof e==`number`&&e!=+e,de=e=>typeof e==`string`&&e.length>1&&e.indexOf(`%`)===e.length-1,F=e=>(typeof e==`number`||e instanceof Number)&&!ue(e),fe=e=>F(e)||typeof e==`string`,pe=0,me=e=>{var t=++pe;return`${e||``}${t}`},he=function(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:0,r=arguments.length>3&&arguments[3]!==void 0&&arguments[3];if(!F(e)&&typeof e!=`string`)return n;var i;if(de(e)){if(t==null)return n;var a=e.indexOf(`%`);i=t*parseFloat(e.slice(0,a))/100}else i=+e;return ue(i)&&(i=n),r&&t!=null&&i>t&&(i=t),i},ge=e=>{if(!Array.isArray(e))return!1;for(var t=e.length,n={},r=0;re&&(typeof t==`function`?t(e):ae(e,t))===n)}var I=e=>e==null,ye=e=>I(e)?e:`${e.charAt(0).toUpperCase()}${e.slice(1)}`;function be(e){return e!=null}function xe(){}function Se(e){if(e)return{x:e.x,y:e.y,upperWidth:`upperWidth`in e?e.upperWidth:e.width,lowerWidth:`lowerWidth`in e?e.lowerWidth:e.width,width:e.width,height:e.height}}function Ce(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function we(e){for(var t=1;t{var t=e.viewBox,n=e.position,r=e.offset,i=r===void 0?0:r,a=e.parentViewBox,o=e.clamp,s=Se(t),c=s.x,l=s.y,u=s.height,d=s.upperWidth,f=s.lowerWidth,p=c,m=c+(d-f)/2,h=(p+m)/2,g=(d+f)/2,_=p+d/2,v=u>=0?1:-1,y=v*i,b=v>0?`end`:`start`,x=v>0?`start`:`end`,S=d>=0?1:-1,C=S*i,w=S>0?`end`:`start`,T=S>0?`start`:`end`,E=a;if(n===`top`){var D={x:p+d/2,y:l-y,horizontalAnchor:`middle`,verticalAnchor:b};return o&&E&&(D.height=Math.max(l-E.y,0),D.width=d),D}if(n===`bottom`){var O={x:m+f/2,y:l+u+y,horizontalAnchor:`middle`,verticalAnchor:x};return o&&E&&(O.height=Math.max(E.y+E.height-(l+u),0),O.width=f),O}if(n===`left`){var k={x:h-C,y:l+u/2,horizontalAnchor:w,verticalAnchor:`middle`};return o&&E&&(k.width=Math.max(k.x-E.x,0),k.height=u),k}if(n===`right`){var A={x:h+g+C,y:l+u/2,horizontalAnchor:T,verticalAnchor:`middle`};return o&&E&&(A.width=Math.max(E.x+E.width-A.x,0),A.height=u),A}var j=o&&E?{width:g,height:u}:{};return n===`insideLeft`?we({x:h+C,y:l+u/2,horizontalAnchor:T,verticalAnchor:`middle`},j):n===`insideRight`?we({x:h+g-C,y:l+u/2,horizontalAnchor:w,verticalAnchor:`middle`},j):n===`insideTop`?we({x:p+d/2,y:l+y,horizontalAnchor:`middle`,verticalAnchor:x},j):n===`insideBottom`?we({x:m+f/2,y:l+u-y,horizontalAnchor:`middle`,verticalAnchor:b},j):n===`insideTopLeft`?we({x:p+C,y:l+y,horizontalAnchor:T,verticalAnchor:x},j):n===`insideTopRight`?we({x:p+d-C,y:l+y,horizontalAnchor:w,verticalAnchor:x},j):n===`insideBottomLeft`?we({x:m+C,y:l+u-y,horizontalAnchor:T,verticalAnchor:b},j):n===`insideBottomRight`?we({x:m+f-C,y:l+u-y,horizontalAnchor:w,verticalAnchor:b},j):n&&typeof n==`object`&&(F(n.x)||de(n.x))&&(F(n.y)||de(n.y))?we({x:c+he(n.x,g),y:l+he(n.y,u),horizontalAnchor:`end`,verticalAnchor:`end`},j):we({x:_,y:l+u/2,horizontalAnchor:`middle`,verticalAnchor:`middle`},j)},ke=[`top`,`left`,`right`,`bottom`];function Ae(e){return e==null?!1:typeof e==`object`||ke.includes(e)}var je=(0,p.createContext)(null);function L(e){return function(){return e}}var Me=Math.PI,Ne=2*Me,Pe=1e-6,Fe=Ne-Pe;function Ie(e){this._+=e[0];for(let t=1,n=e.length;t=0))throw Error(`invalid digits: ${e}`);if(t>15)return Ie;let n=10**t;return function(e){this._+=e[0];for(let t=1,r=e.length;tPe){if(!(Math.abs(u*s-c*l)>Pe)||!i)this._append`L${this._x1=e},${this._y1=t}`;else{let f=n-a,p=r-o,m=s*s+c*c,h=f*f+p*p,g=Math.sqrt(m),_=Math.sqrt(d),v=i*Math.tan((Me-Math.acos((m+d-h)/(2*g*_)))/2),y=v/_,b=v/g;Math.abs(y-1)>Pe&&this._append`L${e+y*l},${t+y*u}`,this._append`A${i},${i},0,0,${+(u*f>l*p)},${this._x1=e+b*s},${this._y1=t+b*c}`}}}arc(e,t,n,r,i,a){if(e=+e,t=+t,n=+n,a=!!a,n<0)throw Error(`negative radius: ${n}`);let o=n*Math.cos(r),s=n*Math.sin(r),c=e+o,l=t+s,u=1^a,d=a?r-i:i-r;this._x1===null?this._append`M${c},${l}`:(Math.abs(this._x1-c)>Pe||Math.abs(this._y1-l)>Pe)&&this._append`L${c},${l}`,n&&(d<0&&(d=d%Ne+Ne),d>Fe?this._append`A${n},${n},0,1,${u},${e-o},${t-s}A${n},${n},0,1,${u},${this._x1=c},${this._y1=l}`:d>Pe&&this._append`A${n},${n},0,${+(d>=Me)},${u},${this._x1=e+n*Math.cos(i)},${this._y1=t+n*Math.sin(i)}`)}rect(e,t,n,r){this._append`M${this._x0=this._x1=+e},${this._y0=this._y1=+t}h${n=+n}v${+r}h${-n}Z`}toString(){return this._}};Re.prototype;function ze(e){let t=3;return e.digits=function(n){if(!arguments.length)return t;if(n==null)t=null;else{let e=Math.floor(n);if(!(e>=0))throw RangeError(`invalid digits: ${n}`);t=e}return e},()=>new Re(t)}Array.prototype.slice;function Be(e){return typeof e==`object`&&`length`in e?e:Array.from(e)}function Ve(e){this._context=e}Ve.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:this._context.lineTo(e,t)}}};function He(e){return new Ve(e)}function Ue(e){return e[0]}function We(e){return e[1]}function Ge(e,t){var n=L(!0),r=null,i=He,a=null,o=ze(s);e=typeof e==`function`?e:e===void 0?Ue:L(e),t=typeof t==`function`?t:t===void 0?We:L(t);function s(s){var c,l=(s=Be(s)).length,u,d=!1,f;for(r??(a=i(f=o())),c=0;c<=l;++c)!(c=d;--f)s.point(_[f],v[f]);s.lineEnd(),s.areaEnd()}}h&&(_[u]=+e(m,u,l),v[u]=+t(m,u,l),s.point(r?+r(m,u,l):_[u],n?+n(m,u,l):v[u]))}if(g)return s=null,g+``||null}function u(){return Ge().defined(i).curve(o).context(a)}return l.x=function(t){return arguments.length?(e=typeof t==`function`?t:L(+t),r=null,l):e},l.x0=function(t){return arguments.length?(e=typeof t==`function`?t:L(+t),l):e},l.x1=function(e){return arguments.length?(r=e==null?null:typeof e==`function`?e:L(+e),l):r},l.y=function(e){return arguments.length?(t=typeof e==`function`?e:L(+e),n=null,l):t},l.y0=function(e){return arguments.length?(t=typeof e==`function`?e:L(+e),l):t},l.y1=function(e){return arguments.length?(n=e==null?null:typeof e==`function`?e:L(+e),l):n},l.lineX0=l.lineY0=function(){return u().x(e).y(t)},l.lineY1=function(){return u().x(e).y(n)},l.lineX1=function(){return u().x(r).y(t)},l.defined=function(e){return arguments.length?(i=typeof e==`function`?e:L(!!e),l):i},l.curve=function(e){return arguments.length?(o=e,a!=null&&(s=o(a)),l):o},l.context=function(e){return arguments.length?(e==null?a=s=null:s=o(a=e),l):a},l}var qe=class{constructor(e,t){this._context=e,this._x=t}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line}point(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:this._x?this._context.bezierCurveTo(this._x0=(this._x0+e)/2,this._y0,this._x0,t,e,t):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+t)/2,e,this._y0,e,t)}this._x0=e,this._y0=t}};function Je(e){return new qe(e,!0)}function Ye(e){return new qe(e,!1)}function Xe(){}function Ze(e,t,n){e._context.bezierCurveTo((2*e._x0+e._x1)/3,(2*e._y0+e._y1)/3,(e._x0+2*e._x1)/3,(e._y0+2*e._y1)/3,(e._x0+4*e._x1+t)/6,(e._y0+4*e._y1+n)/6)}function Qe(e){this._context=e}Qe.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:Ze(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:Ze(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function $e(e){return new Qe(e)}function et(e){this._context=e}et.prototype={areaStart:Xe,areaEnd:Xe,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._x2=e,this._y2=t;break;case 1:this._point=2,this._x3=e,this._y3=t;break;case 2:this._point=3,this._x4=e,this._y4=t,this._context.moveTo((this._x0+4*this._x1+e)/6,(this._y0+4*this._y1+t)/6);break;default:Ze(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function tt(e){return new et(e)}function nt(e){this._context=e}nt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+e)/6,r=(this._y0+4*this._y1+t)/6;this._line?this._context.lineTo(n,r):this._context.moveTo(n,r);break;case 3:this._point=4;default:Ze(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function rt(e){return new nt(e)}function it(e){this._context=e}it.prototype={areaStart:Xe,areaEnd:Xe,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(e,t){e=+e,t=+t,this._point?this._context.lineTo(e,t):(this._point=1,this._context.moveTo(e,t))}};function at(e){return new it(e)}function ot(e){return e<0?-1:1}function st(e,t,n){var r=e._x1-e._x0,i=t-e._x1,a=(e._y1-e._y0)/(r||i<0&&-0),o=(n-e._y1)/(i||r<0&&-0),s=(a*i+o*r)/(r+i);return(ot(a)+ot(o))*Math.min(Math.abs(a),Math.abs(o),.5*Math.abs(s))||0}function ct(e,t){var n=e._x1-e._x0;return n?(3*(e._y1-e._y0)/n-t)/2:t}function lt(e,t,n){var r=e._x0,i=e._y0,a=e._x1,o=e._y1,s=(a-r)/3;e._context.bezierCurveTo(r+s,i+s*t,a-s,o-s*n,a,o)}function ut(e){this._context=e}ut.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:lt(this,this._t0,ct(this,this._t0))}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){var n=NaN;if(e=+e,t=+t,e!==this._x1||t!==this._y1){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3,lt(this,ct(this,n=st(this,e,t)),n);break;default:lt(this,this._t0,n=st(this,e,t))}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t,this._t0=n}}};function dt(e){this._context=new ft(e)}(dt.prototype=Object.create(ut.prototype)).point=function(e,t){ut.prototype.point.call(this,t,e)};function ft(e){this._context=e}ft.prototype={moveTo:function(e,t){this._context.moveTo(t,e)},closePath:function(){this._context.closePath()},lineTo:function(e,t){this._context.lineTo(t,e)},bezierCurveTo:function(e,t,n,r,i,a){this._context.bezierCurveTo(t,e,r,n,a,i)}};function pt(e){return new ut(e)}function mt(e){return new dt(e)}function ht(e){this._context=e}ht.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var e=this._x,t=this._y,n=e.length;if(n){if(this._line?this._context.lineTo(e[0],t[0]):this._context.moveTo(e[0],t[0]),n===2)this._context.lineTo(e[1],t[1]);else for(var r=gt(e),i=gt(t),a=0,o=1;o=0;--t)i[t]=(o[t]-i[t+1])/a[t];for(a[n-1]=(e[n]+i[n-1])/2,t=0;t=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,t),this._context.lineTo(e,t);else{var n=this._x*(1-this._t)+e*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,t)}}this._x=e,this._y=t}};function yt(e){return new vt(e,.5)}function bt(e){return new vt(e,0)}function xt(e){return new vt(e,1)}function St(e,t){if((o=e.length)>1)for(var n=1,r,i,a=e[t[0]],o,s=a.length;n=0;)n[t]=t;return n}function wt(e,t){return e[t]}function Tt(e){let t=[];return t.key=e,t}function Et(){var e=L([]),t=Ct,n=St,r=wt;function i(i){var a=Array.from(e.apply(this,arguments),Tt),o,s=a.length,c=-1,l;for(let e of i)for(o=0,++c;o0){for(var n,r,i=0,a=e[0].length,o;i0){for(var n=0,r=e[t[0]],i,a=r.length;n0)||!((a=(i=e[t[0]]).length)>0))){for(var n=0,r=1,i,a,o;r`radius`in e&&`startAngle`in e&&`endAngle`in e,jt=(e,t)=>{if(!e||typeof e==`function`||typeof e==`boolean`)return null;var n=e;if((0,p.isValidElement)(e)&&(n=e.props),typeof n!=`object`&&typeof n!=`function`)return null;var r={};return Object.keys(n).forEach(e=>{f(e)&&typeof n[e]==`function`&&(r[e]=t||(t=>n[e](n,t)))}),r},Mt=(e,t,n)=>r=>(e(t,n,r),null),Nt=(e,t,n)=>{if(e===null||typeof e!=`object`&&typeof e!=`function`)return null;var r=null;return Object.keys(e).forEach(i=>{var a=e[i];f(i)&&typeof a==`function`&&(r||={},r[i]=Mt(a,t,n))}),r};function Pt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Ft(e){for(var t=1;t(e[t]===void 0&&r[t]!==void 0&&(e[t]=r[t]),e),n)}function Bt(e,t){let n=new Map;for(let r=0;r=0}function Wt(e){return e!=null&&typeof e!=`function`&&Ut(e.length)}function Gt(e){return function(t){return ae(t,e)}}function Kt(e){return e==null||typeof e!=`object`&&typeof e!=`function`}function qt(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function Jt(e){return Object.getOwnPropertySymbols(e).filter(t=>Object.prototype.propertyIsEnumerable.call(e,t))}function Yt(e){return e==null?e===void 0?`[object Undefined]`:`[object Null]`:Object.prototype.toString.call(e)}var Xt=`[object RegExp]`,Zt=`[object String]`,Qt=`[object Number]`,$t=`[object Boolean]`,en=`[object Arguments]`,tn=`[object Symbol]`,nn=`[object Date]`,rn=`[object Map]`,an=`[object Set]`,on=`[object Array]`,sn=`[object Function]`,cn=`[object ArrayBuffer]`,ln=`[object Object]`,un=`[object Error]`,dn=`[object DataView]`,fn=`[object Uint8Array]`,pn=`[object Uint8ClampedArray]`,mn=`[object Uint16Array]`,hn=`[object Uint32Array]`,gn=`[object BigUint64Array]`,_n=`[object Int8Array]`,vn=`[object Int16Array]`,yn=`[object Int32Array]`,bn=`[object BigInt64Array]`,xn=`[object Float32Array]`,Sn=`[object Float64Array]`,Cn=typeof globalThis==`object`&&globalThis||typeof window==`object`&&window||typeof self==`object`&&self||typeof global==`object`&&global||(function(){return this})();function wn(e){return Cn.Buffer!==void 0&&Cn.Buffer.isBuffer(e)}function Tn(e,t){return En(e,void 0,e,new Map,t)}function En(e,t,n,r=new Map,i=void 0){let a=i?.(e,t,n,r);if(a!==void 0)return a;if(Kt(e))return e;if(r.has(e))return r.get(e);if(Array.isArray(e)){let t=Array(e.length);r.set(e,t);for(let a=0;avoid 0)}function Nn(e,t,n,r,i=!1){if(t===e)return!0;switch(typeof t){case`object`:return Pn(e,t,n,r,i);case`function`:return Object.keys(t).length>0?Nn(e,{...t},n,r,i):An(e,t);default:return jn(e)&&i?typeof t!=`string`||t===``:An(e,t)}}function Pn(e,t,n,r,i=!1){if(t==null)return!0;if(Array.isArray(t))return In(e,t,n,r);if(t instanceof Map)return Fn(e,t,n,r);if(t instanceof Set)return Ln(e,t,n,r);let a=Object.keys(t);if(e==null)return i&&a.length===0;if(i)Kt(e)&&(e=Object(e));else{let t=Yt(e);if(t!==`[object Object]`&&t!==`[object Arguments]`)return!1}if(a.length===0)return!0;if(r?.has(t))return r.get(t)===e;r?.set(t,e);try{for(let i=0;ivoid 0)}function zn(e){return e=kn(e),t=>Rn(t,e)}function Bn(e,t){return Tn(e,(n,r,i,a)=>{let o=t?.(n,r,i,a);if(o!==void 0)return o;if(typeof e==`object`){if(Yt(e)===`[object Object]`&&typeof e.constructor!=`function`){let t={};return a.set(e,t),Dn(t,e,i,a),t}switch(Object.prototype.toString.call(e)){case Qt:case Zt:case $t:{let t=new e.constructor(e?.valueOf());return Dn(t,e),t}case en:{let t={};return Dn(t,e),t.length=e.length,t[Symbol.iterator]=e[Symbol.iterator],t}default:return}}})}function Vn(e){return Bn(e)}var Hn=/^(?:0|[1-9]\d*)$/;function Un(e,t=2**53-1){switch(typeof e){case`number`:return Number.isInteger(e)&&e>=0&&e{var n=t(),i=r();function a(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var o=typeof Object.is==`function`?Object.is:a,s=i.useSyncExternalStore,c=n.useRef,l=n.useEffect,u=n.useMemo,d=n.useDebugValue;e.useSyncExternalStoreWithSelector=function(e,t,n,r,i){var a=c(null);if(a.current===null){var f={hasValue:!1,value:null};a.current=f}else f=a.current;a=u(function(){function e(e){if(!a){if(a=!0,s=e,e=r(e),i!==void 0&&f.hasValue){var t=f.value;if(i(t,e))return c=t}return c=e}if(t=c,o(s,e))return t;var n=r(e);return i!==void 0&&i(t,n)?(s=e,t):(s=e,c=n)}var a=!1,s,c,l=n===void 0?null:n;return[function(){return e(t())},l===null?void 0:function(){return e(l())}]},[t,n,r,i]);var p=s(e,a[0],a[1]);return l(function(){f.hasValue=!0,f.value=p},[p]),d(p),p}})),Qn=i(((e,t)=>{t.exports=Zn()})),$n=(0,p.createContext)(null),er=Qn(),tr=e=>e,R=()=>{var e=(0,p.useContext)($n);return e?e.store.dispatch:tr},nr=()=>{},rr=()=>nr,ir=(e,t)=>e===t;function z(e){var t=(0,p.useContext)($n),n=(0,p.useMemo)(()=>t?t=>{if(t!=null)return e(t)}:nr,[t,e]);return(0,er.useSyncExternalStoreWithSelector)(t?t.subscription.addNestedSub:rr,t?t.store.getState:nr,t?t.store.getState:nr,n,ir)}function ar(e,t=`expected a function, instead received ${typeof e}`){if(typeof e!=`function`)throw TypeError(t)}function or(e,t=`expected all items to be functions, instead received the following types: `){if(!e.every(e=>typeof e==`function`)){let n=e.map(e=>typeof e==`function`?`function ${e.name||`unnamed`}()`:typeof e).join(`, `);throw TypeError(`${t}[${n}]`)}}var sr=e=>Array.isArray(e)?e:[e];function cr(e){let t=Array.isArray(e[0])?e[0]:e;return or(t,`createSelector expects all input-selectors to be functions, but received the following types: `),t}function lr(e,t){let n=[],{length:r}=e;for(let i=0;i`u`?ur:WeakRef,fr=0,pr=1;function mr(){return{s:fr,v:void 0,o:null,p:null}}function hr(e){return e instanceof dr?e.deref():e}function gr(e,t={}){let n=mr(),{resultEqualityCheck:r}=t,i,a=0;function o(){let t=n,{length:o}=arguments;for(let e=0,n=o;e{n=mr(),o.resetResultsCount()},o.resultsCount=()=>a,o.resetResultsCount=()=>{a=0},o}function _r(e,...t){let n=typeof e==`function`?{memoize:e,memoizeOptions:t}:e,r=(...e)=>{let t=0,r=0,i,a={},o=e.pop();typeof o==`object`&&(a=o,o=e.pop()),ar(o,`createSelector expects an output function after the inputs, but received: [${typeof o}]`);let{memoize:s,memoizeOptions:c=[],argsMemoize:l=gr,argsMemoizeOptions:u=[]}={...n,...a},d=sr(c),f=sr(u),p=cr(e),m=s(function(){return t++,o.apply(null,arguments)},...d),h=l(function(){r++;let e=lr(p,arguments);return i=m.apply(null,e),i},...f);return Object.assign(h,{resultFunc:o,memoizedResultFunc:m,dependencies:p,dependencyRecomputations:()=>r,resetDependencyRecomputations:()=>{r=0},lastResult:()=>i,recomputations:()=>t,resetRecomputations:()=>{t=0},memoize:s,argsMemoize:l})};return Object.assign(r,{withTypes:()=>r}),r}var B=_r(gr);function vr(e,t=1){let n=[],r=Math.floor(t),i=(e,t)=>{for(let a=0;a{if(e!==t){let r=br(e),i=br(t);if(r===i&&r===0){if(et)return n===`desc`?-1:1}return n===`desc`?i-r:r-i}return 0},Sr=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Cr=/^\w*$/;function wr(e,t){return Array.isArray(e)?!1:typeof e==`number`||typeof e==`boolean`||e==null||te(e)?!0:typeof e==`string`&&(Cr.test(e)||!Sr.test(e))||t!=null&&Object.hasOwn(t,e)}function Tr(e,t,n,r){if(e==null)return[];n=r?void 0:n,Array.isArray(e)||(e=Wt(e)?Array.from(e):Object.values(e)),Array.isArray(t)||(t=t==null?[null]:[t]),t.length===0&&(t=[null]),Array.isArray(n)||(n=n==null?[]:[n]),n=n.map(e=>String(e));let i=(e,t)=>{let n=e,r=0;for(;r0&&r===t.length?n:void 0},a=(e,t)=>{if(e==null)return t;if(t!=null)return typeof e==`object`&&`key`in e?Object.hasOwn(t,e.key)?t[e.key]:i(t,e.path):typeof e==`function`?e(t):Array.isArray(e)?i(t,e):t[e]},o=t.map(e=>(Array.isArray(e)&&e.length===1&&(e=e[0]),e==null||typeof e==`function`||Array.isArray(e)||wr(e)?e:{key:e,path:ie(e)}));return e.map(e=>({original:e,criteria:o.map(t=>a(t,e))})).slice().sort((e,t)=>{for(let r=0;re.original)}function Er(e,...t){let n=t.length;return n>1&&yr(e,t[0],t[1])?t=[]:n>2&&yr(t[0],t[1],t[2])&&(t=[t[0]]),Tr(e,vr(t),[`asc`])}var Dr=e=>e.legend.settings,Or=e=>e.legend.size;B([e=>e.legend.payload,Dr],(e,t)=>{var n=t.itemSorter,r=e.flat(1);return n?Er(r,n):r});function kr(e,t){return Pr(e)||Nr(e,t)||jr(e,t)||Ar()}function Ar(){throw TypeError(`Invalid attempt to destructure non-iterable instance. +import{a as e,c as t,d as n,i as r,l as i,n as a,o,r as s,s as c,t as l,u}from"./index-DOe_Z27O.js";var d=`dangerouslySetInnerHTML.onCopy.onCopyCapture.onCut.onCutCapture.onPaste.onPasteCapture.onCompositionEnd.onCompositionEndCapture.onCompositionStart.onCompositionStartCapture.onCompositionUpdate.onCompositionUpdateCapture.onFocus.onFocusCapture.onBlur.onBlurCapture.onChange.onChangeCapture.onBeforeInput.onBeforeInputCapture.onInput.onInputCapture.onReset.onResetCapture.onSubmit.onSubmitCapture.onInvalid.onInvalidCapture.onLoad.onLoadCapture.onError.onErrorCapture.onKeyDown.onKeyDownCapture.onKeyPress.onKeyPressCapture.onKeyUp.onKeyUpCapture.onAbort.onAbortCapture.onCanPlay.onCanPlayCapture.onCanPlayThrough.onCanPlayThroughCapture.onDurationChange.onDurationChangeCapture.onEmptied.onEmptiedCapture.onEncrypted.onEncryptedCapture.onEnded.onEndedCapture.onLoadedData.onLoadedDataCapture.onLoadedMetadata.onLoadedMetadataCapture.onLoadStart.onLoadStartCapture.onPause.onPauseCapture.onPlay.onPlayCapture.onPlaying.onPlayingCapture.onProgress.onProgressCapture.onRateChange.onRateChangeCapture.onSeeked.onSeekedCapture.onSeeking.onSeekingCapture.onStalled.onStalledCapture.onSuspend.onSuspendCapture.onTimeUpdate.onTimeUpdateCapture.onVolumeChange.onVolumeChangeCapture.onWaiting.onWaitingCapture.onAuxClick.onAuxClickCapture.onClick.onClickCapture.onContextMenu.onContextMenuCapture.onDoubleClick.onDoubleClickCapture.onDrag.onDragCapture.onDragEnd.onDragEndCapture.onDragEnter.onDragEnterCapture.onDragExit.onDragExitCapture.onDragLeave.onDragLeaveCapture.onDragOver.onDragOverCapture.onDragStart.onDragStartCapture.onDrop.onDropCapture.onMouseDown.onMouseDownCapture.onMouseEnter.onMouseLeave.onMouseMove.onMouseMoveCapture.onMouseOut.onMouseOutCapture.onMouseOver.onMouseOverCapture.onMouseUp.onMouseUpCapture.onSelect.onSelectCapture.onTouchCancel.onTouchCancelCapture.onTouchEnd.onTouchEndCapture.onTouchMove.onTouchMoveCapture.onTouchStart.onTouchStartCapture.onPointerDown.onPointerDownCapture.onPointerMove.onPointerMoveCapture.onPointerUp.onPointerUpCapture.onPointerCancel.onPointerCancelCapture.onPointerEnter.onPointerEnterCapture.onPointerLeave.onPointerLeaveCapture.onPointerOver.onPointerOverCapture.onPointerOut.onPointerOutCapture.onGotPointerCapture.onGotPointerCaptureCapture.onLostPointerCapture.onLostPointerCaptureCapture.onScroll.onScrollCapture.onWheel.onWheelCapture.onAnimationStart.onAnimationStartCapture.onAnimationEnd.onAnimationEndCapture.onAnimationIteration.onAnimationIterationCapture.onTransitionEnd.onTransitionEndCapture`.split(`.`);function f(e){return typeof e==`string`&&d.includes(e)}var p=n(t()),m=new Set(`aria-activedescendant.aria-atomic.aria-autocomplete.aria-busy.aria-checked.aria-colcount.aria-colindex.aria-colspan.aria-controls.aria-current.aria-describedby.aria-details.aria-disabled.aria-errormessage.aria-expanded.aria-flowto.aria-haspopup.aria-hidden.aria-invalid.aria-keyshortcuts.aria-label.aria-labelledby.aria-level.aria-live.aria-modal.aria-multiline.aria-multiselectable.aria-orientation.aria-owns.aria-placeholder.aria-posinset.aria-pressed.aria-readonly.aria-relevant.aria-required.aria-roledescription.aria-rowcount.aria-rowindex.aria-rowspan.aria-selected.aria-setsize.aria-sort.aria-valuemax.aria-valuemin.aria-valuenow.aria-valuetext.className.color.height.id.lang.max.media.method.min.name.style.target.width.role.tabIndex.accentHeight.accumulate.additive.alignmentBaseline.allowReorder.alphabetic.amplitude.arabicForm.ascent.attributeName.attributeType.autoReverse.azimuth.baseFrequency.baselineShift.baseProfile.bbox.begin.bias.by.calcMode.capHeight.clip.clipPath.clipPathUnits.clipRule.colorInterpolation.colorInterpolationFilters.colorProfile.colorRendering.contentScriptType.contentStyleType.cursor.cx.cy.d.decelerate.descent.diffuseConstant.direction.display.divisor.dominantBaseline.dur.dx.dy.edgeMode.elevation.enableBackground.end.exponent.externalResourcesRequired.fill.fillOpacity.fillRule.filter.filterRes.filterUnits.floodColor.floodOpacity.focusable.fontFamily.fontSize.fontSizeAdjust.fontStretch.fontStyle.fontVariant.fontWeight.format.from.fx.fy.g1.g2.glyphName.glyphOrientationHorizontal.glyphOrientationVertical.glyphRef.gradientTransform.gradientUnits.hanging.horizAdvX.horizOriginX.href.ideographic.imageRendering.in2.in.intercept.k1.k2.k3.k4.k.kernelMatrix.kernelUnitLength.kerning.keyPoints.keySplines.keyTimes.lengthAdjust.letterSpacing.lightingColor.limitingConeAngle.local.markerEnd.markerHeight.markerMid.markerStart.markerUnits.markerWidth.mask.maskContentUnits.maskUnits.mathematical.mode.numOctaves.offset.opacity.operator.order.orient.orientation.origin.overflow.overlinePosition.overlineThickness.paintOrder.panose1.pathLength.patternContentUnits.patternTransform.patternUnits.pointerEvents.pointsAtX.pointsAtY.pointsAtZ.preserveAlpha.preserveAspectRatio.primitiveUnits.r.radius.refX.refY.renderingIntent.repeatCount.repeatDur.requiredExtensions.requiredFeatures.restart.result.rotate.rx.ry.seed.shapeRendering.slope.spacing.specularConstant.specularExponent.speed.spreadMethod.startOffset.stdDeviation.stemh.stemv.stitchTiles.stopColor.stopOpacity.strikethroughPosition.strikethroughThickness.string.stroke.strokeDasharray.strokeDashoffset.strokeLinecap.strokeLinejoin.strokeMiterlimit.strokeOpacity.strokeWidth.surfaceScale.systemLanguage.tableValues.targetX.targetY.textAnchor.textDecoration.textLength.textRendering.to.transform.u1.u2.underlinePosition.underlineThickness.unicode.unicodeBidi.unicodeRange.unitsPerEm.vAlphabetic.values.vectorEffect.version.vertAdvY.vertOriginX.vertOriginY.vHanging.vIdeographic.viewTarget.visibility.vMathematical.widths.wordSpacing.writingMode.x1.x2.x.xChannelSelector.xHeight.xlinkActuate.xlinkArcrole.xlinkHref.xlinkRole.xlinkShow.xlinkTitle.xlinkType.xmlBase.xmlLang.xmlns.xmlnsXlink.xmlSpace.y1.y2.y.yChannelSelector.z.zoomAndPan.ref.key.angle`.split(`.`));function h(e){return typeof e==`string`&&m.has(e)}function g(e){return typeof e==`string`&&e.startsWith(`data-`)}function _(e){if(typeof e!=`object`||!e)return{};var t={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(h(n)||g(n))&&(t[n]=e[n]);return t}function v(e){if(e==null)return null;if((0,p.isValidElement)(e)&&typeof e.props==`object`&&e.props!==null){var t=e.props;return _(t)}return typeof e==`object`&&!Array.isArray(e)?_(e):null}function y(e){var t={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(h(n)||g(n)||f(n))&&(t[n]=e[n]);return t}function b(e){return e==null?null:(0,p.isValidElement)(e)?y(e.props):typeof e==`object`&&!Array.isArray(e)?y(e):null}var x=[`children`,`width`,`height`,`viewBox`,`className`,`style`,`title`,`desc`];function S(){return S=Object.assign?Object.assign.bind():function(e){for(var t=1;t{var n=e.children,r=e.width,i=e.height,a=e.viewBox,s=e.className,c=e.style,l=e.title,u=e.desc,d=C(e,x),f=a||{width:r,height:i,x:0,y:0},m=o(`recharts-surface`,s);return p.createElement(`svg`,S({},y(d),{className:m,width:r,height:i,style:c,viewBox:`${f.x} ${f.y} ${f.width} ${f.height}`,ref:t}),p.createElement(`title`,null,l),p.createElement(`desc`,null,u),n)}),E=[`children`,`className`];function D(){return D=Object.assign?Object.assign.bind():function(e){for(var t=1;t{var n=e.children,r=e.className,i=O(e,E),a=o(`recharts-layer`,r);return p.createElement(`g`,D({className:a},y(i),{ref:t}),n)});function j(e){return e===`__proto__`}var M=/\.|(\[(?:[^[\]]*|(["'])(?:(?!\2)[^\\]|\\.)*?\2)\])/;function N(e){switch(typeof e){case`number`:case`symbol`:return!1;case`string`:return e===``||e.startsWith(`.`)||e.endsWith(`.`)?!1:M.test(e);default:return!1}}function ee(e){return typeof e==`string`||typeof e==`symbol`?e:Object.is(e?.valueOf?.(),-0)?`-0`:String(e)}function te(e){return typeof e==`symbol`||e instanceof Symbol}function ne(e){return e==null?``:re(e)}function re(e){if(typeof e==`string`)return e;if(Array.isArray(e))return e.map(re).join(`,`);if(te(e))return e.toString();let t=e+``;return t===`0`&&Object.is(Number(e),-0)?`-0`:t}function ie(e){if(Array.isArray(e))return e.map(ee);if(typeof e==`symbol`)return[e];e=ne(e);let t=[],n=e.length;if(n===0)return t;let r=0,i=``,a=``,o=!1,s=!1,c=/^-?\d+(?:\.\d+)?$/;for(e.charCodeAt(0)===46&&t.push(``);r1&&arguments[1]!==void 0?arguments[1]:se),n=Math.round(e*t)/t;return Object.is(n,-0)?0:n}function P(e){var t=[...arguments].slice(1);return e.reduce((e,n,r)=>{var i=t[r-1];return typeof i==`string`?e+i+n:i===void 0?e+n:e+ce(i)+n},``)}var le=e=>e===0?0:e>0?1:-1,ue=e=>typeof e==`number`&&e!=+e,de=e=>typeof e==`string`&&e.length>1&&e.indexOf(`%`)===e.length-1,F=e=>(typeof e==`number`||e instanceof Number)&&!ue(e),fe=e=>F(e)||typeof e==`string`,pe=0,me=e=>{var t=++pe;return`${e||``}${t}`},he=function(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:0,r=arguments.length>3&&arguments[3]!==void 0&&arguments[3];if(!F(e)&&typeof e!=`string`)return n;var i;if(de(e)){if(t==null)return n;var a=e.indexOf(`%`);i=t*parseFloat(e.slice(0,a))/100}else i=+e;return ue(i)&&(i=n),r&&t!=null&&i>t&&(i=t),i},ge=e=>{if(!Array.isArray(e))return!1;for(var t=e.length,n={},r=0;re&&(typeof t==`function`?t(e):ae(e,t))===n)}var I=e=>e==null,ye=e=>I(e)?e:`${e.charAt(0).toUpperCase()}${e.slice(1)}`;function be(e){return e!=null}function xe(){}function Se(e){if(e)return{x:e.x,y:e.y,upperWidth:`upperWidth`in e?e.upperWidth:e.width,lowerWidth:`lowerWidth`in e?e.lowerWidth:e.width,width:e.width,height:e.height}}function Ce(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function we(e){for(var t=1;t{var t=e.viewBox,n=e.position,r=e.offset,i=r===void 0?0:r,a=e.parentViewBox,o=e.clamp,s=Se(t),c=s.x,l=s.y,u=s.height,d=s.upperWidth,f=s.lowerWidth,p=c,m=c+(d-f)/2,h=(p+m)/2,g=(d+f)/2,_=p+d/2,v=u>=0?1:-1,y=v*i,b=v>0?`end`:`start`,x=v>0?`start`:`end`,S=d>=0?1:-1,C=S*i,w=S>0?`end`:`start`,T=S>0?`start`:`end`,E=a;if(n===`top`){var D={x:p+d/2,y:l-y,horizontalAnchor:`middle`,verticalAnchor:b};return o&&E&&(D.height=Math.max(l-E.y,0),D.width=d),D}if(n===`bottom`){var O={x:m+f/2,y:l+u+y,horizontalAnchor:`middle`,verticalAnchor:x};return o&&E&&(O.height=Math.max(E.y+E.height-(l+u),0),O.width=f),O}if(n===`left`){var k={x:h-C,y:l+u/2,horizontalAnchor:w,verticalAnchor:`middle`};return o&&E&&(k.width=Math.max(k.x-E.x,0),k.height=u),k}if(n===`right`){var A={x:h+g+C,y:l+u/2,horizontalAnchor:T,verticalAnchor:`middle`};return o&&E&&(A.width=Math.max(E.x+E.width-A.x,0),A.height=u),A}var j=o&&E?{width:g,height:u}:{};return n===`insideLeft`?we({x:h+C,y:l+u/2,horizontalAnchor:T,verticalAnchor:`middle`},j):n===`insideRight`?we({x:h+g-C,y:l+u/2,horizontalAnchor:w,verticalAnchor:`middle`},j):n===`insideTop`?we({x:p+d/2,y:l+y,horizontalAnchor:`middle`,verticalAnchor:x},j):n===`insideBottom`?we({x:m+f/2,y:l+u-y,horizontalAnchor:`middle`,verticalAnchor:b},j):n===`insideTopLeft`?we({x:p+C,y:l+y,horizontalAnchor:T,verticalAnchor:x},j):n===`insideTopRight`?we({x:p+d-C,y:l+y,horizontalAnchor:w,verticalAnchor:x},j):n===`insideBottomLeft`?we({x:m+C,y:l+u-y,horizontalAnchor:T,verticalAnchor:b},j):n===`insideBottomRight`?we({x:m+f-C,y:l+u-y,horizontalAnchor:w,verticalAnchor:b},j):n&&typeof n==`object`&&(F(n.x)||de(n.x))&&(F(n.y)||de(n.y))?we({x:c+he(n.x,g),y:l+he(n.y,u),horizontalAnchor:`end`,verticalAnchor:`end`},j):we({x:_,y:l+u/2,horizontalAnchor:`middle`,verticalAnchor:`middle`},j)},ke=[`top`,`left`,`right`,`bottom`];function Ae(e){return e==null?!1:typeof e==`object`||ke.includes(e)}var je=(0,p.createContext)(null);function L(e){return function(){return e}}var Me=Math.PI,Ne=2*Me,Pe=1e-6,Fe=Ne-Pe;function Ie(e){this._+=e[0];for(let t=1,n=e.length;t=0))throw Error(`invalid digits: ${e}`);if(t>15)return Ie;let n=10**t;return function(e){this._+=e[0];for(let t=1,r=e.length;tPe){if(!(Math.abs(u*s-c*l)>Pe)||!i)this._append`L${this._x1=e},${this._y1=t}`;else{let f=n-a,p=r-o,m=s*s+c*c,h=f*f+p*p,g=Math.sqrt(m),_=Math.sqrt(d),v=i*Math.tan((Me-Math.acos((m+d-h)/(2*g*_)))/2),y=v/_,b=v/g;Math.abs(y-1)>Pe&&this._append`L${e+y*l},${t+y*u}`,this._append`A${i},${i},0,0,${+(u*f>l*p)},${this._x1=e+b*s},${this._y1=t+b*c}`}}}arc(e,t,n,r,i,a){if(e=+e,t=+t,n=+n,a=!!a,n<0)throw Error(`negative radius: ${n}`);let o=n*Math.cos(r),s=n*Math.sin(r),c=e+o,l=t+s,u=1^a,d=a?r-i:i-r;this._x1===null?this._append`M${c},${l}`:(Math.abs(this._x1-c)>Pe||Math.abs(this._y1-l)>Pe)&&this._append`L${c},${l}`,n&&(d<0&&(d=d%Ne+Ne),d>Fe?this._append`A${n},${n},0,1,${u},${e-o},${t-s}A${n},${n},0,1,${u},${this._x1=c},${this._y1=l}`:d>Pe&&this._append`A${n},${n},0,${+(d>=Me)},${u},${this._x1=e+n*Math.cos(i)},${this._y1=t+n*Math.sin(i)}`)}rect(e,t,n,r){this._append`M${this._x0=this._x1=+e},${this._y0=this._y1=+t}h${n=+n}v${+r}h${-n}Z`}toString(){return this._}};Re.prototype;function ze(e){let t=3;return e.digits=function(n){if(!arguments.length)return t;if(n==null)t=null;else{let e=Math.floor(n);if(!(e>=0))throw RangeError(`invalid digits: ${n}`);t=e}return e},()=>new Re(t)}Array.prototype.slice;function Be(e){return typeof e==`object`&&`length`in e?e:Array.from(e)}function Ve(e){this._context=e}Ve.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:this._context.lineTo(e,t)}}};function He(e){return new Ve(e)}function Ue(e){return e[0]}function We(e){return e[1]}function Ge(e,t){var n=L(!0),r=null,i=He,a=null,o=ze(s);e=typeof e==`function`?e:e===void 0?Ue:L(e),t=typeof t==`function`?t:t===void 0?We:L(t);function s(s){var c,l=(s=Be(s)).length,u,d=!1,f;for(r??(a=i(f=o())),c=0;c<=l;++c)!(c=d;--f)s.point(_[f],v[f]);s.lineEnd(),s.areaEnd()}}h&&(_[u]=+e(m,u,l),v[u]=+t(m,u,l),s.point(r?+r(m,u,l):_[u],n?+n(m,u,l):v[u]))}if(g)return s=null,g+``||null}function u(){return Ge().defined(i).curve(o).context(a)}return l.x=function(t){return arguments.length?(e=typeof t==`function`?t:L(+t),r=null,l):e},l.x0=function(t){return arguments.length?(e=typeof t==`function`?t:L(+t),l):e},l.x1=function(e){return arguments.length?(r=e==null?null:typeof e==`function`?e:L(+e),l):r},l.y=function(e){return arguments.length?(t=typeof e==`function`?e:L(+e),n=null,l):t},l.y0=function(e){return arguments.length?(t=typeof e==`function`?e:L(+e),l):t},l.y1=function(e){return arguments.length?(n=e==null?null:typeof e==`function`?e:L(+e),l):n},l.lineX0=l.lineY0=function(){return u().x(e).y(t)},l.lineY1=function(){return u().x(e).y(n)},l.lineX1=function(){return u().x(r).y(t)},l.defined=function(e){return arguments.length?(i=typeof e==`function`?e:L(!!e),l):i},l.curve=function(e){return arguments.length?(o=e,a!=null&&(s=o(a)),l):o},l.context=function(e){return arguments.length?(e==null?a=s=null:s=o(a=e),l):a},l}var qe=class{constructor(e,t){this._context=e,this._x=t}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line}point(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:this._x?this._context.bezierCurveTo(this._x0=(this._x0+e)/2,this._y0,this._x0,t,e,t):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+t)/2,e,this._y0,e,t)}this._x0=e,this._y0=t}};function Je(e){return new qe(e,!0)}function Ye(e){return new qe(e,!1)}function Xe(){}function Ze(e,t,n){e._context.bezierCurveTo((2*e._x0+e._x1)/3,(2*e._y0+e._y1)/3,(e._x0+2*e._x1)/3,(e._y0+2*e._y1)/3,(e._x0+4*e._x1+t)/6,(e._y0+4*e._y1+n)/6)}function Qe(e){this._context=e}Qe.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:Ze(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:Ze(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function $e(e){return new Qe(e)}function et(e){this._context=e}et.prototype={areaStart:Xe,areaEnd:Xe,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._x2=e,this._y2=t;break;case 1:this._point=2,this._x3=e,this._y3=t;break;case 2:this._point=3,this._x4=e,this._y4=t,this._context.moveTo((this._x0+4*this._x1+e)/6,(this._y0+4*this._y1+t)/6);break;default:Ze(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function tt(e){return new et(e)}function nt(e){this._context=e}nt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+e)/6,r=(this._y0+4*this._y1+t)/6;this._line?this._context.lineTo(n,r):this._context.moveTo(n,r);break;case 3:this._point=4;default:Ze(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function rt(e){return new nt(e)}function it(e){this._context=e}it.prototype={areaStart:Xe,areaEnd:Xe,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(e,t){e=+e,t=+t,this._point?this._context.lineTo(e,t):(this._point=1,this._context.moveTo(e,t))}};function at(e){return new it(e)}function ot(e){return e<0?-1:1}function st(e,t,n){var r=e._x1-e._x0,i=t-e._x1,a=(e._y1-e._y0)/(r||i<0&&-0),o=(n-e._y1)/(i||r<0&&-0),s=(a*i+o*r)/(r+i);return(ot(a)+ot(o))*Math.min(Math.abs(a),Math.abs(o),.5*Math.abs(s))||0}function ct(e,t){var n=e._x1-e._x0;return n?(3*(e._y1-e._y0)/n-t)/2:t}function lt(e,t,n){var r=e._x0,i=e._y0,a=e._x1,o=e._y1,s=(a-r)/3;e._context.bezierCurveTo(r+s,i+s*t,a-s,o-s*n,a,o)}function ut(e){this._context=e}ut.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:lt(this,this._t0,ct(this,this._t0))}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){var n=NaN;if(e=+e,t=+t,e!==this._x1||t!==this._y1){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3,lt(this,ct(this,n=st(this,e,t)),n);break;default:lt(this,this._t0,n=st(this,e,t))}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t,this._t0=n}}};function dt(e){this._context=new ft(e)}(dt.prototype=Object.create(ut.prototype)).point=function(e,t){ut.prototype.point.call(this,t,e)};function ft(e){this._context=e}ft.prototype={moveTo:function(e,t){this._context.moveTo(t,e)},closePath:function(){this._context.closePath()},lineTo:function(e,t){this._context.lineTo(t,e)},bezierCurveTo:function(e,t,n,r,i,a){this._context.bezierCurveTo(t,e,r,n,a,i)}};function pt(e){return new ut(e)}function mt(e){return new dt(e)}function ht(e){this._context=e}ht.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var e=this._x,t=this._y,n=e.length;if(n){if(this._line?this._context.lineTo(e[0],t[0]):this._context.moveTo(e[0],t[0]),n===2)this._context.lineTo(e[1],t[1]);else for(var r=gt(e),i=gt(t),a=0,o=1;o=0;--t)i[t]=(o[t]-i[t+1])/a[t];for(a[n-1]=(e[n]+i[n-1])/2,t=0;t=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,t),this._context.lineTo(e,t);else{var n=this._x*(1-this._t)+e*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,t)}}this._x=e,this._y=t}};function yt(e){return new vt(e,.5)}function bt(e){return new vt(e,0)}function xt(e){return new vt(e,1)}function St(e,t){if((o=e.length)>1)for(var n=1,r,i,a=e[t[0]],o,s=a.length;n=0;)n[t]=t;return n}function wt(e,t){return e[t]}function Tt(e){let t=[];return t.key=e,t}function Et(){var e=L([]),t=Ct,n=St,r=wt;function i(i){var a=Array.from(e.apply(this,arguments),Tt),o,s=a.length,c=-1,l;for(let e of i)for(o=0,++c;o0){for(var n,r,i=0,a=e[0].length,o;i0){for(var n=0,r=e[t[0]],i,a=r.length;n0)||!((a=(i=e[t[0]]).length)>0))){for(var n=0,r=1,i,a,o;r`radius`in e&&`startAngle`in e&&`endAngle`in e,jt=(e,t)=>{if(!e||typeof e==`function`||typeof e==`boolean`)return null;var n=e;if((0,p.isValidElement)(e)&&(n=e.props),typeof n!=`object`&&typeof n!=`function`)return null;var r={};return Object.keys(n).forEach(e=>{f(e)&&typeof n[e]==`function`&&(r[e]=t||(t=>n[e](n,t)))}),r},Mt=(e,t,n)=>r=>(e(t,n,r),null),Nt=(e,t,n)=>{if(e===null||typeof e!=`object`&&typeof e!=`function`)return null;var r=null;return Object.keys(e).forEach(i=>{var a=e[i];f(i)&&typeof a==`function`&&(r||={},r[i]=Mt(a,t,n))}),r};function Pt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Ft(e){for(var t=1;t(e[t]===void 0&&r[t]!==void 0&&(e[t]=r[t]),e),n)}function Bt(e,t){let n=new Map;for(let r=0;r=0}function Wt(e){return e!=null&&typeof e!=`function`&&Ut(e.length)}function Gt(e){return function(t){return ae(t,e)}}function Kt(e){return e==null||typeof e!=`object`&&typeof e!=`function`}function qt(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function Jt(e){return Object.getOwnPropertySymbols(e).filter(t=>Object.prototype.propertyIsEnumerable.call(e,t))}function Yt(e){return e==null?e===void 0?`[object Undefined]`:`[object Null]`:Object.prototype.toString.call(e)}var Xt=`[object RegExp]`,Zt=`[object String]`,Qt=`[object Number]`,$t=`[object Boolean]`,en=`[object Arguments]`,tn=`[object Symbol]`,nn=`[object Date]`,rn=`[object Map]`,an=`[object Set]`,on=`[object Array]`,sn=`[object Function]`,cn=`[object ArrayBuffer]`,ln=`[object Object]`,un=`[object Error]`,dn=`[object DataView]`,fn=`[object Uint8Array]`,pn=`[object Uint8ClampedArray]`,mn=`[object Uint16Array]`,hn=`[object Uint32Array]`,gn=`[object BigUint64Array]`,_n=`[object Int8Array]`,vn=`[object Int16Array]`,yn=`[object Int32Array]`,bn=`[object BigInt64Array]`,xn=`[object Float32Array]`,Sn=`[object Float64Array]`,Cn=typeof globalThis==`object`&&globalThis||typeof window==`object`&&window||typeof self==`object`&&self||typeof global==`object`&&global||(function(){return this})();function wn(e){return Cn.Buffer!==void 0&&Cn.Buffer.isBuffer(e)}function Tn(e,t){return En(e,void 0,e,new Map,t)}function En(e,t,n,r=new Map,i=void 0){let a=i?.(e,t,n,r);if(a!==void 0)return a;if(Kt(e))return e;if(r.has(e))return r.get(e);if(Array.isArray(e)){let t=Array(e.length);r.set(e,t);for(let a=0;avoid 0)}function Nn(e,t,n,r,i=!1){if(t===e)return!0;switch(typeof t){case`object`:return Pn(e,t,n,r,i);case`function`:return Object.keys(t).length>0?Nn(e,{...t},n,r,i):An(e,t);default:return jn(e)&&i?typeof t!=`string`||t===``:An(e,t)}}function Pn(e,t,n,r,i=!1){if(t==null)return!0;if(Array.isArray(t))return In(e,t,n,r);if(t instanceof Map)return Fn(e,t,n,r);if(t instanceof Set)return Ln(e,t,n,r);let a=Object.keys(t);if(e==null)return i&&a.length===0;if(i)Kt(e)&&(e=Object(e));else{let t=Yt(e);if(t!==`[object Object]`&&t!==`[object Arguments]`)return!1}if(a.length===0)return!0;if(r?.has(t))return r.get(t)===e;r?.set(t,e);try{for(let i=0;ivoid 0)}function zn(e){return e=kn(e),t=>Rn(t,e)}function Bn(e,t){return Tn(e,(n,r,i,a)=>{let o=t?.(n,r,i,a);if(o!==void 0)return o;if(typeof e==`object`){if(Yt(e)===`[object Object]`&&typeof e.constructor!=`function`){let t={};return a.set(e,t),Dn(t,e,i,a),t}switch(Object.prototype.toString.call(e)){case Qt:case Zt:case $t:{let t=new e.constructor(e?.valueOf());return Dn(t,e),t}case en:{let t={};return Dn(t,e),t.length=e.length,t[Symbol.iterator]=e[Symbol.iterator],t}default:return}}})}function Vn(e){return Bn(e)}var Hn=/^(?:0|[1-9]\d*)$/;function Un(e,t=2**53-1){switch(typeof e){case`number`:return Number.isInteger(e)&&e>=0&&e{var n=t(),i=r();function a(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var o=typeof Object.is==`function`?Object.is:a,s=i.useSyncExternalStore,c=n.useRef,l=n.useEffect,u=n.useMemo,d=n.useDebugValue;e.useSyncExternalStoreWithSelector=function(e,t,n,r,i){var a=c(null);if(a.current===null){var f={hasValue:!1,value:null};a.current=f}else f=a.current;a=u(function(){function e(e){if(!a){if(a=!0,s=e,e=r(e),i!==void 0&&f.hasValue){var t=f.value;if(i(t,e))return c=t}return c=e}if(t=c,o(s,e))return t;var n=r(e);return i!==void 0&&i(t,n)?(s=e,t):(s=e,c=n)}var a=!1,s,c,l=n===void 0?null:n;return[function(){return e(t())},l===null?void 0:function(){return e(l())}]},[t,n,r,i]);var p=s(e,a[0],a[1]);return l(function(){f.hasValue=!0,f.value=p},[p]),d(p),p}})),Qn=i(((e,t)=>{t.exports=Zn()})),$n=(0,p.createContext)(null),er=Qn(),tr=e=>e,R=()=>{var e=(0,p.useContext)($n);return e?e.store.dispatch:tr},nr=()=>{},rr=()=>nr,ir=(e,t)=>e===t;function z(e){var t=(0,p.useContext)($n),n=(0,p.useMemo)(()=>t?t=>{if(t!=null)return e(t)}:nr,[t,e]);return(0,er.useSyncExternalStoreWithSelector)(t?t.subscription.addNestedSub:rr,t?t.store.getState:nr,t?t.store.getState:nr,n,ir)}function ar(e,t=`expected a function, instead received ${typeof e}`){if(typeof e!=`function`)throw TypeError(t)}function or(e,t=`expected all items to be functions, instead received the following types: `){if(!e.every(e=>typeof e==`function`)){let n=e.map(e=>typeof e==`function`?`function ${e.name||`unnamed`}()`:typeof e).join(`, `);throw TypeError(`${t}[${n}]`)}}var sr=e=>Array.isArray(e)?e:[e];function cr(e){let t=Array.isArray(e[0])?e[0]:e;return or(t,`createSelector expects all input-selectors to be functions, but received the following types: `),t}function lr(e,t){let n=[],{length:r}=e;for(let i=0;i`u`?ur:WeakRef,fr=0,pr=1;function mr(){return{s:fr,v:void 0,o:null,p:null}}function hr(e){return e instanceof dr?e.deref():e}function gr(e,t={}){let n=mr(),{resultEqualityCheck:r}=t,i,a=0;function o(){let t=n,{length:o}=arguments;for(let e=0,n=o;e{n=mr(),o.resetResultsCount()},o.resultsCount=()=>a,o.resetResultsCount=()=>{a=0},o}function _r(e,...t){let n=typeof e==`function`?{memoize:e,memoizeOptions:t}:e,r=(...e)=>{let t=0,r=0,i,a={},o=e.pop();typeof o==`object`&&(a=o,o=e.pop()),ar(o,`createSelector expects an output function after the inputs, but received: [${typeof o}]`);let{memoize:s,memoizeOptions:c=[],argsMemoize:l=gr,argsMemoizeOptions:u=[]}={...n,...a},d=sr(c),f=sr(u),p=cr(e),m=s(function(){return t++,o.apply(null,arguments)},...d),h=l(function(){r++;let e=lr(p,arguments);return i=m.apply(null,e),i},...f);return Object.assign(h,{resultFunc:o,memoizedResultFunc:m,dependencies:p,dependencyRecomputations:()=>r,resetDependencyRecomputations:()=>{r=0},lastResult:()=>i,recomputations:()=>t,resetRecomputations:()=>{t=0},memoize:s,argsMemoize:l})};return Object.assign(r,{withTypes:()=>r}),r}var B=_r(gr);function vr(e,t=1){let n=[],r=Math.floor(t),i=(e,t)=>{for(let a=0;a{if(e!==t){let r=br(e),i=br(t);if(r===i&&r===0){if(et)return n===`desc`?-1:1}return n===`desc`?i-r:r-i}return 0},Sr=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Cr=/^\w*$/;function wr(e,t){return Array.isArray(e)?!1:typeof e==`number`||typeof e==`boolean`||e==null||te(e)?!0:typeof e==`string`&&(Cr.test(e)||!Sr.test(e))||t!=null&&Object.hasOwn(t,e)}function Tr(e,t,n,r){if(e==null)return[];n=r?void 0:n,Array.isArray(e)||(e=Wt(e)?Array.from(e):Object.values(e)),Array.isArray(t)||(t=t==null?[null]:[t]),t.length===0&&(t=[null]),Array.isArray(n)||(n=n==null?[]:[n]),n=n.map(e=>String(e));let i=(e,t)=>{let n=e,r=0;for(;r0&&r===t.length?n:void 0},a=(e,t)=>{if(e==null)return t;if(t!=null)return typeof e==`object`&&`key`in e?Object.hasOwn(t,e.key)?t[e.key]:i(t,e.path):typeof e==`function`?e(t):Array.isArray(e)?i(t,e):t[e]},o=t.map(e=>(Array.isArray(e)&&e.length===1&&(e=e[0]),e==null||typeof e==`function`||Array.isArray(e)||wr(e)?e:{key:e,path:ie(e)}));return e.map(e=>({original:e,criteria:o.map(t=>a(t,e))})).slice().sort((e,t)=>{for(let r=0;re.original)}function Er(e,...t){let n=t.length;return n>1&&yr(e,t[0],t[1])?t=[]:n>2&&yr(t[0],t[1],t[2])&&(t=[t[0]]),Tr(e,vr(t),[`asc`])}var Dr=e=>e.legend.settings,Or=e=>e.legend.size;B([e=>e.legend.payload,Dr],(e,t)=>{var n=t.itemSorter,r=e.flat(1);return n?Er(r,n):r});function kr(e,t){return Pr(e)||Nr(e,t)||jr(e,t)||Ar()}function Ar(){throw TypeError(`Invalid attempt to destructure non-iterable instance. In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function jr(e,t){if(e){if(typeof e==`string`)return Mr(e,t);var n={}.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Mr(e,t):void 0}}function Mr(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nFr||Math.abs(e.left-t.left)>Fr||Math.abs(e.top-t.top)>Fr||Math.abs(e.width-t.width)>Fr}function Lr(e){var t=e.getBoundingClientRect();return{height:t.height,left:t.left,top:t.top,width:t.width}}function Rr(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],t=kr((0,p.useState)({height:0,left:0,top:0,width:0}),2),n=t[0],r=t[1],i=(0,p.useRef)(null),a=(0,p.useRef)(n);a.current=n;var o=(0,p.useCallback)(e=>{if(i.current!=null&&(i.current.disconnect(),i.current=null),e!=null){var t=Lr(e);if(Ir(t,a.current)&&r(t),typeof ResizeObserver<`u`){var n=new ResizeObserver(()=>{var t=Lr(e);Ir(t,a.current)&&r(t)});n.observe(e),i.current=n}}},[...e]);return(0,p.useEffect)(()=>()=>{var e;(e=i.current)==null||e.disconnect()},[]),[n,o]}function zr(e){return`Minified Redux error #${e}; visit https://redux.js.org/Errors?code=${e} for the full message or use the non-minified dev environment for full errors. `}var Br=typeof Symbol==`function`&&Symbol.observable||`@@observable`,Vr=()=>Math.random().toString(36).substring(7).split(``).join(`.`),Hr={INIT:`@@redux/INIT${Vr()}`,REPLACE:`@@redux/REPLACE${Vr()}`,PROBE_UNKNOWN_ACTION:()=>`@@redux/PROBE_UNKNOWN_ACTION${Vr()}`};function Ur(e){if(typeof e!=`object`||!e)return!1;let t=e;for(;Object.getPrototypeOf(t)!==null;)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t||Object.getPrototypeOf(e)===null}function Wr(e,t,n){if(typeof e!=`function`)throw Error(zr(2));if(typeof t==`function`&&typeof n==`function`||typeof n==`function`&&typeof arguments[3]==`function`)throw Error(zr(0));if(typeof t==`function`&&n===void 0&&(n=t,t=void 0),n!==void 0){if(typeof n!=`function`)throw Error(zr(1));return n(Wr)(e,t)}let r=e,i=t,a=new Map,o=a,s=0,c=!1;function l(){o===a&&(o=new Map,a.forEach((e,t)=>{o.set(t,e)}))}function u(){if(c)throw Error(zr(3));return i}function d(e){if(typeof e!=`function`)throw Error(zr(4));if(c)throw Error(zr(5));let t=!0;l();let n=s++;return o.set(n,e),function(){if(t){if(c)throw Error(zr(6));t=!1,l(),o.delete(n),a=null}}}function f(e){if(!Ur(e))throw Error(zr(7));if(e.type===void 0)throw Error(zr(8));if(typeof e.type!=`string`)throw Error(zr(17));if(c)throw Error(zr(9));try{c=!0,i=r(i,e)}finally{c=!1}return(a=o).forEach(e=>{e()}),e}function p(e){if(typeof e!=`function`)throw Error(zr(10));r=e,f({type:Hr.REPLACE})}function m(){let e=d;return{subscribe(t){if(typeof t!=`object`||!t)throw Error(zr(11));function n(){let e=t;e.next&&e.next(u())}return n(),{unsubscribe:e(n)}},[Br](){return this}}}return f({type:Hr.INIT}),{dispatch:f,subscribe:d,getState:u,replaceReducer:p,[Br]:m}}function Gr(e){Object.keys(e).forEach(t=>{let n=e[t];if(n(void 0,{type:Hr.INIT})===void 0)throw Error(zr(12));if(n(void 0,{type:Hr.PROBE_UNKNOWN_ACTION()})===void 0)throw Error(zr(13))})}function Kr(e){let t=Object.keys(e),n={};for(let r=0;re:e.length===1?e[0]:e.reduce((e,t)=>(...n)=>e(t(...n)))}function Jr(...e){return t=>(n,r)=>{let i=t(n,r),a=()=>{throw Error(zr(15))},o={getState:i.getState,dispatch:(e,...t)=>a(e,...t)};return a=qr(...e.map(e=>e(o)))(i.dispatch),{...i,dispatch:a}}}function Yr(e){return Ur(e)&&`type`in e&&typeof e.type==`string`}var Xr=Symbol.for(`immer-nothing`),Zr=Symbol.for(`immer-draftable`),Qr=Symbol.for(`immer-state`);function $r(e,...t){throw Error(`[Immer] minified error nr: ${e}. Full error at: https://bit.ly/3cXEKWf`)}var ei=Object,ti=ei.getPrototypeOf,ni=`constructor`,ri=`prototype`,ii=`configurable`,ai=`enumerable`,oi=`writable`,si=`value`,ci=e=>!!e&&!!e[Qr];function li(e){return e?fi(e)||yi(e)||!!e[Zr]||!!e[ni]?.[Zr]||bi(e)||xi(e):!1}var ui=ei[ri][ni].toString(),di=new WeakMap;function fi(e){if(!e||!Si(e))return!1;let t=ti(e);if(t===null||t===ei[ri])return!0;let n=ei.hasOwnProperty.call(t,ni)&&t[ni];if(n===Object)return!0;if(!Ci(n))return!1;let r=di.get(n);return r===void 0&&(r=Function.toString.call(n),di.set(n,r)),r===ui}function pi(e,t,n=!0){mi(e)===0?(n?Reflect.ownKeys(e):ei.keys(e)).forEach(n=>{t(n,e[n],e)}):e.forEach((n,r)=>t(r,n,e))}function mi(e){let t=e[Qr];return t?t.type_:yi(e)?1:bi(e)?2:xi(e)?3:0}var hi=(e,t,n=mi(e))=>n===2?e.has(t):ei[ri].hasOwnProperty.call(e,t),gi=(e,t,n=mi(e))=>n===2?e.get(t):e[t],_i=(e,t,n,r=mi(e))=>{r===2?e.set(t,n):r===3?e.add(n):e[t]=n};function vi(e,t){return e===t?e!==0||1/e==1/t:e!==e&&t!==t}var yi=Array.isArray,bi=e=>e instanceof Map,xi=e=>e instanceof Set,Si=e=>typeof e==`object`,Ci=e=>typeof e==`function`,wi=e=>typeof e==`boolean`;function Ti(e){let t=+e;return Number.isInteger(t)&&String(t)===e}var Ei=e=>e.copy_||e.base_,Di=e=>e.modified_?e.copy_:e.base_;function Oi(e,t){if(bi(e))return new Map(e);if(xi(e))return new Set(e);if(yi(e))return Array[ri].slice.call(e);let n=fi(e);if(t===!0||t===`class_only`&&!n){let t=ei.getOwnPropertyDescriptors(e);delete t[Qr];let n=Reflect.ownKeys(t);for(let r=0;r1&&ei.defineProperties(e,{set:ji,add:ji,clear:ji,delete:ji}),ei.freeze(e),t&&pi(e,(e,t)=>{ki(t,!0)},!1),e)}function Ai(){$r(2)}var ji={[si]:Ai};function Mi(e){return e===null||!Si(e)||ei.isFrozen(e)}var Ni=`MapSet`,Pi=`Patches`,Fi=`ArrayMethods`,Ii={};function Li(e){let t=Ii[e];return t||$r(0,e),t}var Ri=e=>!!Ii[e],zi,Bi=()=>zi,Vi=(e,t)=>({drafts_:[],parent_:e,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0,handledSet_:new Set,processedForPatches_:new Set,mapSetPlugin_:Ri(Ni)?Li(Ni):void 0,arrayMethodsPlugin_:Ri(Fi)?Li(Fi):void 0});function Hi(e,t){t&&(e.patchPlugin_=Li(Pi),e.patches_=[],e.inversePatches_=[],e.patchListener_=t)}function Ui(e){Wi(e),e.drafts_.forEach(Ki),e.drafts_=null}function Wi(e){e===zi&&(zi=e.parent_)}var Gi=e=>zi=Vi(zi,e);function Ki(e){let t=e[Qr];t.type_===0||t.type_===1?t.revoke_():t.revoked_=!0}function qi(e,t){t.unfinalizedDrafts_=t.drafts_.length;let n=t.drafts_[0];if(e!==void 0&&e!==n){n[Qr].modified_&&(Ui(t),$r(4)),li(e)&&(e=Ji(t,e));let{patchPlugin_:r}=t;r&&r.generateReplacementPatches_(n[Qr].base_,e,t)}else e=Ji(t,n);return Yi(t,e,!0),Ui(t),t.patches_&&t.patchListener_(t.patches_,t.inversePatches_),e===Xr?void 0:e}function Ji(e,t){if(Mi(t))return t;let n=t[Qr];if(!n)return ra(t,e.handledSet_,e);if(!Zi(n,e))return t;if(!n.modified_)return n.base_;if(!n.finalized_){let{callbacks_:t}=n;if(t)for(;t.length>0;)t.pop()(e);ta(n,e)}return n.copy_}function Yi(e,t,n=!1){!e.parent_&&e.immer_.autoFreeze_&&e.canAutoFreeze_&&ki(t,n)}function Xi(e){e.finalized_=!0,e.scope_.unfinalizedDrafts_--}var Zi=(e,t)=>e.scope_===t,Qi=[];function $i(e,t,n,r){let i=Ei(e),a=e.type_;if(r!==void 0&&gi(i,r,a)===t){_i(i,r,n,a);return}if(!e.draftLocations_){let t=e.draftLocations_=new Map;pi(i,(e,n)=>{if(ci(n)){let r=t.get(n)||[];r.push(e),t.set(n,r)}})}let o=e.draftLocations_.get(t)??Qi;for(let e of o)_i(i,e,n,a)}function ea(e,t,n){e.callbacks_.push(function(r){let i=t;if(!i||!Zi(i,r))return;r.mapSetPlugin_?.fixSetContents(i);let a=Di(i);$i(e,i.draft_??i,a,n),ta(i,r)})}function ta(e,t){if(e.modified_&&!e.finalized_&&(e.type_===3||e.type_===1&&e.allIndicesReassigned_||(e.assigned_?.size??0)>0)){let{patchPlugin_:n}=t;if(n){let r=n.getPath(e);r&&n.generatePatches_(e,r,t)}Xi(e)}}function na(e,t,n){let{scope_:r}=e;if(ci(n)){let i=n[Qr];Zi(i,r)&&i.callbacks_.push(function(){fa(e),$i(e,n,Di(i),t)})}else li(n)&&e.callbacks_.push(function(){let i=Ei(e);e.type_===3?i.has(n)&&ra(n,r.handledSet_,r):gi(i,t,e.type_)===n&&r.drafts_.length>1&&(e.assigned_.get(t)??!1)===!0&&e.copy_&&ra(gi(e.copy_,t,e.type_),r.handledSet_,r)})}function ra(e,t,n){return!n.immer_.autoFreeze_&&n.unfinalizedDrafts_<1||ci(e)||t.has(e)||!li(e)||Mi(e)?e:(t.add(e),pi(e,(r,i)=>{if(ci(i)){let t=i[Qr];Zi(t,n)&&(_i(e,r,Di(t),e.type_),Xi(t))}else li(i)&&ra(i,t,n)}),e)}function ia(e,t){let n=yi(e),r={type_:+!!n,scope_:t?t.scope_:Bi(),modified_:!1,finalized_:!1,assigned_:void 0,parent_:t,base_:e,draft_:null,copy_:null,revoke_:null,isManual_:!1,callbacks_:void 0},i=r,a=aa;n&&(i=[r],a=oa);let{revoke:o,proxy:s}=Proxy.revocable(i,a);return r.draft_=s,r.revoke_=o,[s,r]}var aa={get(e,t){if(t===Qr)return e;let n=e.scope_.arrayMethodsPlugin_,r=e.type_===1&&typeof t==`string`;if(r&&n?.isArrayOperationMethod(t))return n.createMethodInterceptor(e,t);let i=Ei(e);if(!hi(i,t,e.type_))return la(e,i,t);let a=i[t];if(e.finalized_||!li(a)||r&&e.operationMethod&&n?.isMutatingArrayMethod(e.operationMethod)&&Ti(t))return a;if(a===sa(e.base_,t)||ca(e,t,a)){fa(e);let n=e.type_===1?+t:t,r=ma(e.scope_,a,e,n);return e.copy_[n]=r}return a},has(e,t){return t in Ei(e)},ownKeys(e){return Reflect.ownKeys(Ei(e))},set(e,t,n){let r=ua(Ei(e),t);if(r?.set)return r.set.call(e.draft_,n),!0;if(!e.modified_){let r=sa(Ei(e),t),i=r?.[Qr];if(i&&i.base_===n)return e.copy_[t]=n,e.assigned_.set(t,!1),!0;if(vi(n,r)&&(n!==void 0||hi(e.base_,t,e.type_)))return!0;fa(e),da(e)}return e.copy_[t]===n&&(n!==void 0||hi(e.copy_,t,e.type_))||Number.isNaN(n)&&Number.isNaN(e.copy_[t])?!0:(e.copy_[t]=n,e.assigned_.set(t,!0),na(e,t,n),!0)},deleteProperty(e,t){return fa(e),sa(e.base_,t)!==void 0||t in e.base_?(e.assigned_.set(t,!1),da(e)):e.assigned_.delete(t),e.copy_&&delete e.copy_[t],!0},getOwnPropertyDescriptor(e,t){let n=Ei(e),r=Reflect.getOwnPropertyDescriptor(n,t);return r&&{[oi]:!0,[ii]:e.type_!==1||t!==`length`,[ai]:r[ai],[si]:n[t]}},defineProperty(){$r(11)},getPrototypeOf(e){return ti(e.base_)},setPrototypeOf(){$r(12)}},oa={};for(let e in aa){let t=aa[e];oa[e]=function(){let e=arguments;return e[0]=e[0][0],t.apply(this,e)}}oa.deleteProperty=function(e,t){return oa.set.call(this,e,t,void 0)},oa.set=function(e,t,n){return aa.set.call(this,e[0],t,n,e[0])};function sa(e,t){let n=e[Qr];return(n?Ei(n):e)[t]}function ca(e,t,n){return e.type_!==1||!e.allIndicesReassigned_||e.assigned_?.get(t)||!li(n)||n[Qr]?!1:e.baseRefs_.has(n)}function la(e,t,n){let r=ua(t,n);return r?si in r?r[si]:r.get?.call(e.draft_):void 0}function ua(e,t){if(!(t in e))return;let n=ti(e);for(;n;){let e=Object.getOwnPropertyDescriptor(n,t);if(e)return e;n=ti(n)}}function da(e){e.modified_||(e.modified_=!0,e.parent_&&da(e.parent_))}function fa(e){e.copy_||=(e.assigned_=new Map,Oi(e.base_,e.scope_.immer_.useStrictShallowCopy_))}var pa=class{constructor(e){this.autoFreeze_=!0,this.useStrictShallowCopy_=!1,this.useStrictIteration_=!1,this.produce=(e,t,n)=>{if(Ci(e)&&!Ci(t)){let n=t;t=e;let r=this;return function(e=n,...i){return r.produce(e,e=>t.call(this,e,...i))}}Ci(t)||$r(6),n!==void 0&&!Ci(n)&&$r(7);let r;if(li(e)){let i=Gi(this),a=ma(i,e,void 0),o=!0;try{r=t(a),o=!1}finally{o?Ui(i):Wi(i)}return Hi(i,n),qi(r,i)}if(!e||!Si(e)){if(r=t(e),r===void 0&&(r=e),r===Xr&&(r=void 0),this.autoFreeze_&&ki(r,!0),n){let t=[],i=[];Li(Pi).generateReplacementPatches_(e,r,{patches_:t,inversePatches_:i}),n(t,i)}return r}$r(1,e)},this.produceWithPatches=(e,t)=>{if(Ci(e))return(t,...n)=>this.produceWithPatches(t,t=>e(t,...n));let n,r;return[this.produce(e,t,(e,t)=>{n=e,r=t}),n,r]},wi(e?.autoFreeze)&&this.setAutoFreeze(e.autoFreeze),wi(e?.useStrictShallowCopy)&&this.setUseStrictShallowCopy(e.useStrictShallowCopy),wi(e?.useStrictIteration)&&this.setUseStrictIteration(e.useStrictIteration)}createDraft(e){li(e)||$r(8),ci(e)&&(e=ha(e));let t=Gi(this),n=ma(t,e,void 0);return n[Qr].isManual_=!0,Wi(t),n}finishDraft(e,t){let n=e&&e[Qr];(!n||!n.isManual_)&&$r(9);let{scope_:r}=n;return Hi(r,t),qi(void 0,r)}setAutoFreeze(e){this.autoFreeze_=e}setUseStrictShallowCopy(e){this.useStrictShallowCopy_=e}setUseStrictIteration(e){this.useStrictIteration_=e}shouldUseStrictIteration(){return this.useStrictIteration_}applyPatches(e,t){let n;for(n=t.length-1;n>=0;n--){let r=t[n];if(r.path.length===0&&r.op===`replace`){e=r.value;break}}n>-1&&(t=t.slice(n+1));let r=Li(Pi).applyPatches_;return ci(e)?r(e,t):this.produce(e,e=>r(e,t))}};function ma(e,t,n,r){let[i,a]=bi(t)?Li(Ni).proxyMap_(t,n):xi(t)?Li(Ni).proxySet_(t,n):ia(t,n);return(n?.scope_??Bi()).drafts_.push(i),a.callbacks_=n?.callbacks_??[],a.key_=r,n&&r!==void 0?ea(n,a,r):a.callbacks_.push(function(e){e.mapSetPlugin_?.fixSetContents(a);let{patchPlugin_:t}=e;a.modified_&&t&&t.generatePatches_(a,[],e)}),i}function ha(e){return ci(e)||$r(10,e),ga(e)}function ga(e){if(!li(e)||Mi(e))return e;let t=e[Qr],n,r=!0;if(t){if(!t.modified_)return t.base_;t.finalized_=!0,n=Oi(e,t.scope_.immer_.useStrictShallowCopy_),r=t.scope_.immer_.shouldUseStrictIteration()}else n=Oi(e,!0);return pi(n,(e,t)=>{_i(n,e,ga(t))},r),t&&(t.finalized_=!1),n}globalThis.Iterator?.from;var _a=new pa().produce,V=e=>e;function va(e){return({dispatch:t,getState:n})=>r=>i=>typeof i==`function`?i(t,n,e):r(i)}var ya=va(),ba=va,xa=typeof window<`u`&&window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__?window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__:function(){if(arguments.length!==0)return typeof arguments[0]==`object`?qr:qr.apply(null,arguments)};typeof window<`u`&&window.__REDUX_DEVTOOLS_EXTENSION__&&window.__REDUX_DEVTOOLS_EXTENSION__;function Sa(e,t){function n(...n){if(t){let r=t(...n);if(!r)throw Error(jo(0));return{type:e,payload:r.payload,...`meta`in r&&{meta:r.meta},...`error`in r&&{error:r.error}}}return{type:e,payload:n[0]}}return n.toString=()=>`${e}`,n.type=e,n.match=t=>Yr(t)&&t.type===e,n}var Ca=class e extends Array{constructor(...t){super(...t),Object.setPrototypeOf(this,e.prototype)}static get[Symbol.species](){return e}concat(...e){return super.concat.apply(this,e)}prepend(...t){return t.length===1&&Array.isArray(t[0])?new e(...t[0].concat(this)):new e(...t.concat(this))}};function wa(e){return li(e)?_a(e,()=>{}):e}function Ta(e,t,n){return e.has(t)?e.get(t):e.set(t,n(t)).get(t)}function Ea(e){return typeof e==`boolean`}var Da=()=>function(e){let{thunk:t=!0,immutableCheck:n=!0,serializableCheck:r=!0,actionCreatorCheck:i=!0}=e??{},a=new Ca;return t&&(Ea(t)?a.push(ya):a.push(ba(t.extraArgument))),a},Oa=`RTK_autoBatch`,H=()=>e=>({payload:e,meta:{[Oa]:!0}}),ka=e=>t=>{setTimeout(t,e)},Aa=(e,t)=>n=>{let r=!1,i=()=>{r||(r=!0,cancelAnimationFrame(a),clearTimeout(o),n())},a=e(i),o=setTimeout(i,t)},ja=(e={type:`raf`})=>t=>(...n)=>{let r=t(...n),i=!0,a=!1,o=!1,s=new Set,c=e.type===`tick`?queueMicrotask:e.type===`raf`?typeof window<`u`&&window.requestAnimationFrame?Aa(window.requestAnimationFrame,100):ka(10):e.type===`callback`?e.queueNotification:ka(e.timeout),l=()=>{o=!1,a&&(a=!1,s.forEach(e=>e()))};return Object.assign({},r,{subscribe(e){let t=r.subscribe(()=>i&&e());return s.add(e),()=>{t(),s.delete(e)}},dispatch(e){try{return i=!e?.meta?.[Oa],a=!i,a&&(o||(o=!0,c(l))),r.dispatch(e)}finally{i=!0}}})},Ma=e=>function(t){let{autoBatch:n=!0}=t??{},r=new Ca(e);return n&&r.push(ja(typeof n==`object`?n:void 0)),r};function Na(e){let t=Da(),{reducer:n=void 0,middleware:r,devTools:i=!0,duplicateMiddlewareCheck:a=!0,preloadedState:o=void 0,enhancers:s=void 0}=e||{},c;if(typeof n==`function`)c=n;else if(Ur(n))c=Kr(n);else throw Error(jo(1));let l;l=typeof r==`function`?r(t):t();let u=qr;i&&(u=xa({trace:!1,...typeof i==`object`&&i}));let d=Ma(Jr(...l)),f=typeof s==`function`?s(d):d(),p=u(...f);return Wr(c,o,p)}function Pa(e){let t={},n=[],r,i={addCase(e,n){let r=typeof e==`string`?e:e.type;if(!r)throw Error(jo(28));if(r in t)throw Error(jo(29));return t[r]=n,i},addAsyncThunk(e,r){return r.pending&&(t[e.pending.type]=r.pending),r.rejected&&(t[e.rejected.type]=r.rejected),r.fulfilled&&(t[e.fulfilled.type]=r.fulfilled),r.settled&&n.push({matcher:e.settled,reducer:r.settled}),i},addMatcher(e,t){return n.push({matcher:e,reducer:t}),i},addDefaultCase(e){return r=e,i}};return e(i),[t,n,r]}function Fa(e){return typeof e==`function`}function Ia(e,t){let[n,r,i]=Pa(t),a;if(Fa(e))a=()=>wa(e());else{let t=wa(e);a=()=>t}function o(e=a(),t){let o=[n[t.type],...r.filter(({matcher:e})=>e(t)).map(({reducer:e})=>e)];return o.filter(e=>!!e).length===0&&(o=[i]),o.reduce((e,n)=>{if(n){if(ci(e)){let r=n(e,t);return r===void 0?e:r}if(li(e))return _a(e,e=>n(e,t));{let r=n(e,t);if(r===void 0){if(e===null)return e;throw Error(`A case reducer on a non-draftable value must not return undefined`)}return r}}return e},e)}return o.getInitialState=a,o}var La=`ModuleSymbhasOwnPr-0123456789ABCDEFGHNRVfgctiUvz_KqYTJkLxpZXIjQW`,Ra=(e=21)=>{let t=``,n=e;for(;n--;)t+=La[Math.random()*64|0];return t},za=Symbol.for(`rtk-slice-createasyncthunk`);function Ba(e,t){return`${e}/${t}`}function Va({creators:e}={}){let t=e?.asyncThunk?.[za];return function(e){let{name:n,reducerPath:r=n}=e;if(!n)throw Error(jo(11));let i=(typeof e.reducers==`function`?e.reducers(Wa()):e.reducers)||{},a=Object.keys(i),o={sliceCaseReducersByName:{},sliceCaseReducersByType:{},actionCreators:{},sliceMatchers:[]},s={addCase(e,t){let n=typeof e==`string`?e:e.type;if(!n)throw Error(jo(12));if(n in o.sliceCaseReducersByType)throw Error(jo(13));return o.sliceCaseReducersByType[n]=t,s},addMatcher(e,t){return o.sliceMatchers.push({matcher:e,reducer:t}),s},exposeAction(e,t){return o.actionCreators[e]=t,s},exposeCaseReducer(e,t){return o.sliceCaseReducersByName[e]=t,s}};a.forEach(r=>{let a=i[r],o={reducerName:r,type:Ba(n,r),createNotation:typeof e.reducers==`function`};Ka(a)?Ja(o,a,s,t):Ga(o,a,s)});function c(){let[t={},n=[],r=void 0]=typeof e.extraReducers==`function`?Pa(e.extraReducers):[e.extraReducers],i={...t,...o.sliceCaseReducersByType};return Ia(e.initialState,e=>{for(let t in i)e.addCase(t,i[t]);for(let t of o.sliceMatchers)e.addMatcher(t.matcher,t.reducer);for(let t of n)e.addMatcher(t.matcher,t.reducer);r&&e.addDefaultCase(r)})}let l=e=>e,u=new Map,d=new WeakMap,f;function p(e,t){return f||=c(),f(e,t)}function m(){return f||=c(),f.getInitialState()}function h(t,n=!1){function r(e){let i=e[t];return i===void 0&&n&&(i=Ta(d,r,m)),i}function i(t=l){return Ta(Ta(u,n,()=>new WeakMap),t,()=>{let r={};for(let[i,a]of Object.entries(e.selectors??{}))r[i]=Ha(a,t,()=>Ta(d,t,m),n);return r})}return{reducerPath:t,getSelectors:i,get selectors(){return i(r)},selectSlice:r}}let g={name:n,reducer:p,actions:o.actionCreators,caseReducers:o.sliceCaseReducersByName,getInitialState:m,...h(r),injectInto(e,{reducerPath:t,...n}={}){let i=t??r;return e.inject({reducerPath:i,reducer:p},n),{...g,...h(i,!0)}}};return g}}function Ha(e,t,n,r){function i(i,...a){let o=t(i);return o===void 0&&r&&(o=n()),e(o,...a)}return i.unwrapped=e,i}var Ua=Va();function Wa(){function e(e,t){return{_reducerDefinitionType:`asyncThunk`,payloadCreator:e,...t}}return e.withTypes=()=>e,{reducer(e){return Object.assign({[e.name](...t){return e(...t)}}[e.name],{_reducerDefinitionType:`reducer`})},preparedReducer(e,t){return{_reducerDefinitionType:`reducerWithPrepare`,prepare:e,reducer:t}},asyncThunk:e}}function Ga({type:e,reducerName:t,createNotation:n},r,i){let a,o;if(`reducer`in r){if(n&&!qa(r))throw Error(jo(17));a=r.reducer,o=r.prepare}else a=r;i.addCase(e,a).exposeCaseReducer(t,a).exposeAction(t,o?Sa(e,o):Sa(e))}function Ka(e){return e._reducerDefinitionType===`asyncThunk`}function qa(e){return e._reducerDefinitionType===`reducerWithPrepare`}function Ja({type:e,reducerName:t},n,r,i){if(!i)throw Error(jo(18));let{payloadCreator:a,fulfilled:o,pending:s,rejected:c,settled:l,options:u}=n,d=i(e,a,u);r.exposeAction(t,d),o&&r.addCase(d.fulfilled,o),s&&r.addCase(d.pending,s),c&&r.addCase(d.rejected,c),l&&r.addMatcher(d.settled,l),r.exposeCaseReducer(t,{fulfilled:o||Ya,pending:s||Ya,rejected:c||Ya,settled:l||Ya})}function Ya(){}var Xa=`task`,Za=`listener`,Qa=`completed`,$a=`cancelled`,eo=`task-${$a}`,to=`task-${Qa}`,no=`${Za}-${$a}`,ro=`${Za}-${Qa}`,io=class{constructor(e){this.code=e,this.message=`${Xa} ${$a} (reason: ${e})`}code;name=`TaskAbortError`;message},ao=(e,t)=>{if(typeof e!=`function`)throw TypeError(jo(32))},oo=()=>{},so=(e,t=oo)=>(e.catch(t),e),co=(e,t)=>(e.addEventListener(`abort`,t,{once:!0}),()=>e.removeEventListener(`abort`,t)),lo=e=>{if(e.aborted)throw new io(e.reason)};function uo(e,t){let n=oo;return new Promise((r,i)=>{let a=()=>i(new io(e.reason));if(e.aborted){a();return}n=co(e,a),t.finally(()=>n()).then(r,i)}).finally(()=>{n=oo})}var fo=async(e,t)=>{try{return await Promise.resolve(),{status:`ok`,value:await e()}}catch(e){return{status:e instanceof io?`cancelled`:`rejected`,error:e}}finally{t?.()}},po=e=>t=>so(uo(e,t).then(t=>(lo(e),t))),mo=e=>{let t=po(e);return e=>t(new Promise(t=>setTimeout(t,e)))},{assign:ho}=Object,go={},_o=`listenerMiddleware`,vo=(e,t)=>{let n=t=>co(e,()=>t.abort(e.reason));return(r,i)=>{ao(r,`taskExecutor`);let a=new AbortController;n(a);let o=fo(async()=>{lo(e),lo(a.signal);let t=await r({pause:po(a.signal),delay:mo(a.signal),signal:a.signal});return lo(a.signal),t},()=>a.abort(to));return i?.autoJoin&&t.push(o.catch(oo)),{result:po(e)(o),cancel(){a.abort(eo)}}}},yo=(e,t)=>{let n=async(n,r)=>{lo(t);let i=()=>{},a=[new Promise((t,r)=>{let a=e({predicate:n,effect:(e,n)=>{n.unsubscribe(),t([e,n.getState(),n.getOriginalState()])}});i=()=>{a(),r()}})];r!=null&&a.push(new Promise(e=>setTimeout(e,r,null)));try{let e=await uo(t,Promise.race(a));return lo(t),e}finally{i()}};return((e,t)=>so(n(e,t)))},bo=e=>{let{type:t,actionCreator:n,matcher:r,predicate:i,effect:a}=e;if(t)i=Sa(t).match;else if(n)t=n.type,i=n.match;else if(r)i=r;else if(!i)throw Error(jo(21));return ao(a,`options.listener`),{predicate:i,type:t,effect:a}},xo=ho(e=>{let{type:t,predicate:n,effect:r}=bo(e);return{id:Ra(),effect:r,type:t,predicate:n,pending:new Set,unsubscribe:()=>{throw Error(jo(22))}}},{withTypes:()=>xo}),So=(e,t)=>{let{type:n,effect:r,predicate:i}=bo(t);return Array.from(e.values()).find(e=>(typeof n==`string`?e.type===n:e.predicate===i)&&e.effect===r)},Co=e=>{e.pending.forEach(e=>{e.abort(no)})},wo=(e,t)=>()=>{for(let e of t.keys())Co(e);e.clear()},To=(e,t,n)=>{try{e(t,n)}catch(e){setTimeout(()=>{throw e},0)}},Eo=ho(Sa(`${_o}/add`),{withTypes:()=>Eo}),Do=Sa(`${_o}/removeAll`),Oo=ho(Sa(`${_o}/remove`),{withTypes:()=>Oo}),ko=(...e)=>{console.error(`${_o}/error`,...e)},Ao=(e={})=>{let t=new Map,n=new Map,r=e=>{let t=n.get(e)??0;n.set(e,t+1)},i=e=>{let t=n.get(e)??1;t===1?n.delete(e):n.set(e,t-1)},{extra:a,onError:o=ko}=e;ao(o,`onError`);let s=e=>(e.unsubscribe=()=>t.delete(e.id),t.set(e.id,e),t=>{e.unsubscribe(),t?.cancelActive&&Co(e)}),c=(e=>{let n=So(t,e)??xo(e);return s(n)});ho(c,{withTypes:()=>c});let l=e=>{let n=So(t,e);return n&&(n.unsubscribe(),e.cancelActive&&Co(n)),!!n};ho(l,{withTypes:()=>l});let u=async(e,n,s,l)=>{let u=new AbortController,d=yo(c,u.signal),f=[];try{e.pending.add(u),r(e),await Promise.resolve(e.effect(n,ho({},s,{getOriginalState:l,condition:(e,t)=>d(e,t).then(Boolean),take:d,delay:mo(u.signal),pause:po(u.signal),extra:a,signal:u.signal,fork:vo(u.signal,f),unsubscribe:e.unsubscribe,subscribe:()=>{t.set(e.id,e)},cancelActiveListeners:()=>{e.pending.forEach((e,t,n)=>{e!==u&&(e.abort(no),n.delete(e))})},cancel:()=>{u.abort(no),e.pending.delete(u)},throwIfCancelled:()=>{lo(u.signal)}})))}catch(e){e instanceof io||To(o,e,{raisedBy:`effect`})}finally{await Promise.all(f),u.abort(ro),i(e),e.pending.delete(u)}},d=wo(t,n);return{middleware:e=>n=>r=>{if(!Yr(r))return n(r);if(Eo.match(r))return c(r.payload);if(Do.match(r)){d();return}if(Oo.match(r))return l(r.payload);let i=e.getState(),a=()=>{if(i===go)throw Error(jo(23));return i},s;try{if(s=n(r),t.size>0){let n=e.getState(),s=Array.from(t.values());for(let t of s){let s=!1;try{s=t.predicate(r,n,i)}catch(e){s=!1,To(o,e,{raisedBy:`predicate`})}s&&u(t,r,e,a)}}}finally{i=go}return s},startListening:c,stopListening:l,clearListeners:d}};function jo(e){return`Minified Redux Toolkit error #${e}; visit https://redux-toolkit.js.org/Errors?code=${e} for the full message or use the non-minified dev environment for full errors. `}var Mo=Ua({name:`chartLayout`,initialState:{layoutType:`horizontal`,width:0,height:0,margin:{top:5,right:5,bottom:5,left:5},scale:1},reducers:{setLayout(e,t){e.layoutType=t.payload},setChartSize(e,t){e.width=t.payload.width,e.height=t.payload.height},setMargin(e,t){e.margin.top=t.payload.top??0,e.margin.right=t.payload.right??0,e.margin.bottom=t.payload.bottom??0,e.margin.left=t.payload.left??0},setScale(e,t){e.scale=t.payload}}}),No=Mo.actions,Po=No.setMargin,Fo=No.setLayout,Io=No.setChartSize,Lo=No.setScale,Ro=Mo.reducer;function zo(e,t,n){return Array.isArray(e)&&e&&t+n!==0?e.slice(t,n+1):e}function U(e){return Number.isFinite(e)}function Bo(e){return typeof e==`number`&&e>0&&Number.isFinite(e)}function Vo(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Ho(e){for(var t=1;t{if(t&&n){var r=n.width,i=n.height,a=t.align,o=t.verticalAlign,s=t.layout,c=t.position,l=t.offset,u=l===void 0?0:l;if(c!=null){if(Ae(c)){if(c===`top`&&F(e.top))return Ho(Ho({},e),{},{top:e.top+(i||0)+u});if(c===`bottom`&&F(e.bottom))return Ho(Ho({},e),{},{bottom:e.bottom+(i||0)+u});if(c===`left`&&F(e.left))return Ho(Ho({},e),{},{left:e.left+(r||0)+u});if(c===`right`&&F(e.right))return Ho(Ho({},e),{},{right:e.right+(r||0)+u})}return e}if((s===`vertical`||s===`horizontal`&&o===`middle`)&&a!==`center`&&F(e[a]))return Ho(Ho({},e),{},{[a]:e[a]+(r||0)});if((s===`horizontal`||s===`vertical`&&a===`center`)&&o!==`middle`&&F(e[o]))return Ho(Ho({},e),{},{[o]:e[o]+(i||0)})}return e},qo=(e,t)=>e===`horizontal`&&t===`xAxis`||e===`vertical`&&t===`yAxis`||e===`centric`&&t===`angleAxis`||e===`radial`&&t===`radiusAxis`,Jo=(e,t,n,r)=>{if(r)return e.map(e=>e.coordinate);var i,a,o=e.map(e=>(e.coordinate===t&&(i=!0),e.coordinate===n&&(a=!0),e.coordinate));return i||o.push(t),a||o.push(n),o},Yo=(e,t,n)=>{if(!e)return null;var r=e.duplicateDomain,i=e.type,a=e.range,o=e.scale,s=e.realScaleType,c=e.isCategorical,l=e.categoricalDomain,u=e.tickCount,d=e.ticks,f=e.niceTicks,p=e.axisType;if(!o)return null;var m=s===`scaleBand`&&o.bandwidth?o.bandwidth()/2:2,h=(t||n)&&i===`category`&&o.bandwidth?o.bandwidth()/m:0;return h=p===`angleAxis`&&a&&a.length>=2?le(a[0]-a[1])*2*h:h,t&&(d||f)?(d||f||[]).map((e,t)=>{var n=r?r.indexOf(e):e,i=o.map(n);return U(i)?{coordinate:i+h,value:e,offset:h,index:t}:null}).filter(be):c&&l?l.map((e,t)=>{var n=o.map(e);return U(n)?{coordinate:n+h,value:e,index:t,offset:h}:null}).filter(be):o.ticks&&!n&&u!=null?o.ticks(u).map((e,t)=>{var n=o.map(e);return U(n)?{coordinate:n+h,value:e,index:t,offset:h}:null}).filter(be):o.domain().map((e,t)=>{var n=o.map(e);return U(n)?{coordinate:n+h,value:r?r[e]:e,index:t,offset:h}:null}).filter(be)},Xo={sign:e=>{var t=e.length;if(!(t<=0)){var n=e[0]?.length;if(!(n==null||n<=0))for(var r=0;r=0?(s[0]=i,i+=u,s[1]=i):(s[0]=a,a+=u,s[1]=a)}}}},expand:Dt,none:St,silhouette:Ot,wiggle:kt,positive:e=>{var t=e.length;if(!(t<=0)){var n=e[0]?.length;if(!(n==null||n<=0))for(var r=0;r=0?(o[0]=i,i+=s,o[1]=i):(o[0]=0,o[1]=0)}}}}},Zo=(e,t,n)=>{var r=Xo[n]??St,i=Et().keys(t).value((e,t)=>Number(W(e,t,0))).order(Ct).offset(r)(e);return i.forEach((n,r)=>{n.forEach((n,i)=>{var a=W(e[i],t[r],0);Array.isArray(a)&&a.length===2&&F(a[0])&&F(a[1])&&(n[0]=a[0],n[1]=a[1])})}),i};function Qo(e){return e==null?void 0:String(e)}function $o(e){var t=e.axis,n=e.ticks,r=e.bandSize,i=e.entry,a=e.index,o=e.dataKey;if(t.type===`category`){if(!t.allowDuplicatedCategory&&t.dataKey&&!I(i[t.dataKey])){var s=ve(n,`value`,i[t.dataKey]);if(s)return s.coordinate+r/2}return n!=null&&n[a]?n[a].coordinate+r/2:null}var c=W(i,I(o)?t.dataKey:o),l=t.scale.map(c);return F(l)?l:null}var es=e=>{var t=e.flat(2).filter(F);return[Math.min(...t),Math.max(...t)]},ts=e=>[e[0]===1/0?0:e[0],e[1]===-1/0?0:e[1]],ns=(e,t,n)=>{if(e!=null&&Object.keys(e).length!==0)return ts(Object.keys(e).reduce((r,i)=>{var a=e[i];if(!a)return r;var o=a.stackedData.reduce((e,r)=>{var i=es(zo(r,t,n));return!U(i[0])||!U(i[1])?e:[Math.min(e[0],i[0]),Math.max(e[1],i[1])]},[1/0,-1/0]);return[Math.min(o[0],r[0]),Math.max(o[1],r[1])]},[1/0,-1/0]))},rs=/^dataMin[\s]*-[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/,is=/^dataMax[\s]*\+[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/,as=(e,t,n)=>{if(e&&e.scale&&e.scale.bandwidth){var r=e.scale.bandwidth();if(!n||r>0)return r}if(e&&t&&t.length>=2){for(var i=Er(t,e=>e.coordinate),a=[],o=0,s=1,c=i.length;su&&(d=Math.min(f,d));return d===1/0?0:d}return n?void 0:0};function os(e){var t=e.tooltipEntrySettings,n=e.dataKey,r=e.payload,i=e.value,a=e.name;return Ho(Ho({},t),{},{dataKey:n,payload:r,value:i,name:a})}function ss(e,t){if(e!=null)return String(e);if(typeof t==`string`)return t}var cs=(e,t)=>{if(t===`horizontal`)return e.relativeX;if(t===`vertical`)return e.relativeY},ls=(e,t)=>t===`centric`?e.angle:e.radius,us=e=>e.layout.width,ds=e=>e.layout.height,fs=e=>e.layout.scale,ps=e=>e.layout.margin,ms=B(e=>e.cartesianAxis.xAxis,e=>Object.values(e)),hs=B(e=>e.cartesianAxis.yAxis,e=>Object.values(e)),gs=`data-recharts-item-index`;function _s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function vs(e){for(var t=1;te.brush.height;function Cs(e){return hs(e).reduce((e,t)=>t.orientation===`left`&&!t.mirror&&!t.hide?e+(typeof t.width==`number`?t.width:60):e,0)}function ws(e){return hs(e).reduce((e,t)=>t.orientation===`right`&&!t.mirror&&!t.hide?e+(typeof t.width==`number`?t.width:60):e,0)}function Ts(e){return ms(e).reduce((e,t)=>t.orientation===`top`&&!t.mirror&&!t.hide?e+(typeof t.height==`number`?t.height:30):e,0)}function Es(e){return ms(e).reduce((e,t)=>t.orientation===`bottom`&&!t.mirror&&!t.hide?e+(typeof t.height==`number`?t.height:30):e,0)}var Ds=B([us,ds,ps,Ss,Cs,ws,Ts,Es,Dr,Or],(e,t,n,r,i,a,o,s,c,l)=>{var u={left:(n.left||0)+i,right:(n.right||0)+a},d=vs(vs({},{top:(n.top||0)+o,bottom:(n.bottom||0)+s}),u),f=d.bottom;d.bottom+=r,d=Ko(d,c,l);var p=e-d.left-d.right,m=t-d.top-d.bottom;return vs(vs({brushBottom:f},d),{},{width:Math.max(p,0),height:Math.max(m,0)})}),Os=B(Ds,e=>({x:e.left,y:e.top,width:e.width,height:e.height})),ks=B(us,ds,(e,t)=>({x:0,y:0,width:e,height:t})),As=(0,p.createContext)(null),js=()=>(0,p.useContext)(As)!=null,Ms=e=>e.brush,Ns=B([Ms,Ds,ps],(e,t,n)=>({height:e.height,x:F(e.x)?e.x:t.left,y:F(e.y)?e.y:t.top+t.height+t.brushBottom-(n?.bottom||0),width:F(e.width)?e.width:t.width}));function Ps(e,t,{signal:n,edges:r}={}){let i,a=null,o=r!=null&&r.includes(`leading`),s=r==null||r.includes(`trailing`),c=()=>{a!==null&&(e.apply(i,a),i=void 0,a=null)},l=()=>{s&&c(),p()},u=null,d=()=>{u!=null&&clearTimeout(u),u=setTimeout(()=>{u=null,l()},t)},f=()=>{u!==null&&(clearTimeout(u),u=null)},p=()=>{f(),i=void 0,a=null},m=()=>{c()},h=function(...e){if(n?.aborted)return;i=this,a=e;let t=u==null;d(),o&&t&&c()};return h.schedule=d,h.cancel=p,h.flush=m,n?.addEventListener(`abort`,p,{once:!0}),h}function Fs(e,t=0,n={}){typeof n!=`object`&&(n={});let{leading:r=!1,trailing:i=!0,maxWait:a}=n,o=[,,];r&&(o[0]=`leading`),i&&(o[1]=`trailing`);let s,c=null,l=Ps(function(...t){s=e.apply(this,t),c=null},t,{edges:o}),u=function(...t){return a!=null&&(c===null&&(c=Date.now()),Date.now()-c>=a)?((r||i)&&(s=e.apply(this,t)),c=Date.now(),l.cancel(),l.schedule(),s):(l.apply(this,t),s)};return u.cancel=l.cancel,u.flush=()=>(l.flush(),s),u}function Is(e,t=0,n={}){let{leading:r=!0,trailing:i=!0}=n;return Fs(e,t,{leading:r,maxWait:t,trailing:i})}var Ls=function(e,t){var n=[...arguments].slice(2);if(typeof console<`u`&&console.warn&&(t===void 0&&console.warn(`LogUtils requires an error message argument`),!e)){if(t===void 0)console.warn(`Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.`);else{var r=0;console.warn(t.replace(/%s/g,()=>n[r++]))}}},Rs={width:`100%`,height:`100%`,debounce:0,minWidth:0,initialDimension:{width:-1,height:-1}},zs=(e,t,n)=>{var r=n.width,i=r===void 0?Rs.width:r,a=n.height,o=a===void 0?Rs.height:a,s=n.aspect,c=n.maxHeight,l=de(i)?e:Number(i),u=de(o)?t:Number(o);return s&&s>0&&(l?u=l/s:u&&(l=u*s),c&&u!=null&&u>c&&(u=c)),{calculatedWidth:l,calculatedHeight:u}},Bs={width:0,height:0,overflow:`visible`},Vs={width:0,overflowX:`visible`},Hs={height:0,overflowY:`visible`},Us={},Ws=e=>{var t=e.width,n=e.height,r=de(t),i=de(n);return r&&i?Bs:r?Vs:i?Hs:Us};function Gs(e){var t=e.width,n=e.height,r=e.aspect,i=t,a=n;return i===void 0&&a===void 0?(i=Rs.width,a=Rs.height):i===void 0?i=r&&r>0?void 0:Rs.width:a===void 0&&(a=r&&r>0?void 0:Rs.height),{width:i,height:a}}var Ks=[`aspect`,`initialDimension`,`width`,`height`,`minWidth`,`minHeight`,`maxHeight`,`children`,`debounce`,`id`,`className`,`onResize`,`style`];function qs(){return qs=Object.assign?Object.assign.bind():function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n({width:n,height:r}),[n,r]);return cc(i)?p.createElement(sc.Provider,{value:i},t):null}var uc=()=>(0,p.useContext)(sc),dc=(0,p.forwardRef)((e,t)=>{var n=e.aspect,r=e.initialDimension,i=r===void 0?Rs.initialDimension:r,a=e.width,s=e.height,c=e.minWidth,l=c===void 0?Rs.minWidth:c,u=e.minHeight,d=e.maxHeight,f=e.children,m=e.debounce,h=m===void 0?Rs.debounce:m,g=e.id,_=e.className,v=e.onResize,y=e.style,b=y===void 0?{}:y,x=ac(e,Ks),S=(0,p.useRef)(null),C=(0,p.useRef)();C.current=v,(0,p.useImperativeHandle)(t,()=>S.current);var w=$s((0,p.useState)({containerWidth:i.width,containerHeight:i.height}),2),T=w[0],E=w[1],D=(0,p.useCallback)((e,t)=>{E(n=>{var r=Math.round(e),i=Math.round(t);return n.containerWidth===r&&n.containerHeight===i?n:{containerWidth:r,containerHeight:i}})},[]);(0,p.useEffect)(()=>{if(S.current==null||typeof ResizeObserver>`u`)return xe;var e=e=>{var t,n=e[0];if(n!=null){var r=n.contentRect,i=r.width,a=r.height;D(i,a),(t=C.current)==null||t.call(C,i,a)}};h>0&&(e=Is(e,h,{trailing:!0,leading:!1}));var t=new ResizeObserver(e),n=S.current.getBoundingClientRect(),r=n.width,i=n.height;return D(r,i),t.observe(S.current),()=>{t.disconnect()}},[D,h]);var O=T.containerWidth,k=T.containerHeight;Ls(!n||n>0,`The aspect(%s) must be greater than zero.`,n);var A=zs(O,k,{width:a,height:s,aspect:n,maxHeight:d}),j=A.calculatedWidth,M=A.calculatedHeight;return Ls(O<0||k<0||j!=null&&j>0||M!=null&&M>0,`The width(%s) and height(%s) of chart should be greater than 0, please check the style of container, or the props width(%s) and height(%s), diff --git a/internal/webui/static/assets/index-C4p-2Dwo.js b/internal/webui/static/assets/index-C4p-2Dwo.js deleted file mode 100644 index fbc42fa8..00000000 --- a/internal/webui/static/assets/index-C4p-2Dwo.js +++ /dev/null @@ -1,28 +0,0 @@ -var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},c=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},l=(n,r,o)=>(o=n==null?{}:e(i(n)),c(r||!n||!n.__esModule||!a.call(n,`default`)?t(o,`default`,{value:n,enumerable:!0}):o,n));(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var u=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=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,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var S=Array.isArray;function C(){}var w={H:null,A:null,T:null,S:null},T=Object.prototype.hasOwnProperty;function E(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function D(e,t){return E(e.type,t,e.props)}function O(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function k(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var A=/\/+/g;function j(e,t){return typeof e==`object`&&e&&e.key!=null?k(``+e.key):t.toString(36)}function M(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(C,C):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function N(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,N(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+j(e,0):a,S(o)?(i=``,c!=null&&(i=c.replace(A,`$&/`)+`/`),N(o,r,i,``,function(e){return e})):o!=null&&(O(o)&&(o=D(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(A,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(S(e))for(var u=0;u{t.exports=u()})),f=o((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m){if(n(c)!==null)m=!0,S||(S=!0,O());else{var t=n(l);t!==null&&j(x,t.startTime-e)}}}var S=!1,C=-1,w=5,T=-1;function E(){return g?!0:!(e.unstable_now()-Tt&&E());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&j(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?O():S=!1}}}var O;if(typeof y==`function`)O=function(){y(D)};else if(typeof MessageChannel<`u`){var k=new MessageChannel,A=k.port2;k.port1.onmessage=D,O=function(){A.postMessage(null)}}else O=function(){_(D,0)};function j(t,n){C=_(function(){t(e.unstable_now())},n)}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(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,j(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,O()))),r},e.unstable_shouldYield=E,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),p=o(((e,t)=>{t.exports=f()})),m=o((e=>{var t=d();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=m()})),g=o((e=>{var t=p(),n=d(),r=h();function i(e){var t=`https://react.dev/errors/`+e;if(1te||(e.current=R[te],R[te]=null,te--)}function z(e,t){te++,R[te]=e.current,e.current=t}var ie=ne(null),ae=ne(null),oe=ne(null),se=ne(null);function ce(e,t){switch(z(oe,t),z(ae,e),z(ie,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Kd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Kd(t),e=qd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}re(ie),z(ie,e)}function le(){re(ie),re(ae),re(oe)}function ue(e){e.memoizedState!==null&&z(se,e);var t=ie.current,n=qd(t,e.type);t!==n&&(z(ae,e),z(ie,n))}function de(e){ae.current===e&&(re(ie),re(ae)),se.current===e&&(re(se),rp._currentValue=L)}var fe,pe;function me(e){if(fe===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);fe=t&&t[1]||``,pe=-1)`:-1i||c[r]!==l[i]){var u=` -`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{he=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?me(n):``}function _e(e,t){switch(e.tag){case 26:case 27:case 5:return me(e.type);case 16:return me(`Lazy`);case 13:return e.child!==t&&t!==null?me(`Suspense Fallback`):me(`Suspense`);case 19:return me(`SuspenseList`);case 0:case 15:return ge(e.type,!1);case 11:return ge(e.type.render,!1);case 1:return ge(e.type,!0);case 31:return me(`Activity`);default:return``}}function ve(e){try{var t=``,n=null;do t+=_e(e,n),n=e,e=e.return;while(e);return t}catch(e){return` -Error generating stack: `+e.message+` -`+e.stack}}var ye=Object.prototype.hasOwnProperty,be=t.unstable_scheduleCallback,xe=t.unstable_cancelCallback,Se=t.unstable_shouldYield,Ce=t.unstable_requestPaint,we=t.unstable_now,Te=t.unstable_getCurrentPriorityLevel,Ee=t.unstable_ImmediatePriority,De=t.unstable_UserBlockingPriority,Oe=t.unstable_NormalPriority,ke=t.unstable_LowPriority,Ae=t.unstable_IdlePriority,je=t.log,Me=t.unstable_setDisableYieldValue,Ne=null,Pe=null;function Fe(e){if(typeof je==`function`&&Me(e),Pe&&typeof Pe.setStrictMode==`function`)try{Pe.setStrictMode(Ne,e)}catch{}}var Ie=Math.clz32?Math.clz32:ze,Le=Math.log,Re=Math.LN2;function ze(e){return e>>>=0,e===0?32:31-(Le(e)/Re|0)|0}var Be=256,Ve=262144,He=4194304;function Ue(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function We(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=Ue(n))):i=Ue(o):i=Ue(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=Ue(n))):i=Ue(o)):i=Ue(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function Ge(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function Ke(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32: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 t+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 qe(){var e=He;return He<<=1,!(He&62914560)&&(He=4194304),e}function Je(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Ye(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Xe(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),ln=!1;if(cn)try{var un={};Object.defineProperty(un,"passive",{get:function(){ln=!0}}),window.addEventListener(`test`,un,un),window.removeEventListener(`test`,un,un)}catch{ln=!1}var dn=null,fn=null,pn=null;function mn(){if(pn)return pn;var e,t=fn,n=t.length,r,i=`value`in dn?dn.value:dn.textContent,a=i.length;for(e=0;e=Kn),Yn=` `,Xn=!1;function Zn(e,t){switch(e){case`keyup`:return Wn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function Qn(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var $n=!1;function er(e,t){switch(e){case`compositionend`:return Qn(t);case`keypress`:return t.which===32?(Xn=!0,Yn):null;case`textInput`:return e=t.data,e===Yn&&Xn?null:e;default:return null}}function tr(e,t){if($n)return e===`compositionend`||!Gn&&Zn(e,t)?(e=mn(),pn=fn=dn=null,$n=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=Cr(n)}}function Tr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Tr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Er(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Ft(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Ft(e.document)}return t}function Dr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var Or=cn&&`documentMode`in document&&11>=document.documentMode,kr=null,Ar=null,jr=null,Mr=!1;function Nr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Mr||kr==null||kr!==Ft(r)||(r=kr,`selectionStart`in r&&Dr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),jr&&Sr(jr,r)||(jr=r,r=Md(Ar,`onSelect`),0>=o,i-=o,Ti=1<<32-Ie(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),Pi&&Di(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),Pi&&Di(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return Pi&&Di(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),Pi&&Di(a,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===y&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case _:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===y){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===O&&Oa(l)===r.type){n(e,r.sibling),c=a(r,o.props),Fa(c,o),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}o.type===y?(c=fi(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=di(o.type,o.key,o.props,null,e.mode,c),Fa(c,o),c.return=e,e=c)}return s(e);case v:a:{for(l=o.key;r!==null;){if(r.key===l){if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}c=hi(o,e.mode,c),c.return=e,e=c}return s(e);case O:return o=Oa(o),b(e,r,o,c)}if(ee(o))return h(e,r,o,c);if(M(o)){if(l=M(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),g(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,Pa(o),c);if(o.$$typeof===C)return b(e,r,na(e,o),c);Ia(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=pi(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{Na=0;var i=b(e,t,n,r);return Ma=null,i}catch(t){if(t===Sa||t===wa)throw t;var a=si(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var Ra=La(!0),za=La(!1),Ba=!1;function Va(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Ha(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function Ua(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Wa(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,G&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=ii(e),ri(e,null,n),t}return ei(e,r,t,n),ii(e)}function Ga(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Qe(e,n)}}function Ka(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var qa=!1;function Ja(){if(qa){var e=pa;if(e!==null)throw e}}function Ya(e,t,n,r){qa=!1;var i=e.updateQueue;Ba=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(Hl&f)===f:(r&f)===f){f!==0&&f===fa&&(qa=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var h=e,g=s;f=t;var _=n;switch(g.tag){case 1:if(h=g.payload,typeof h==`function`){d=h.call(_,d,f);break a}d=h;break a;case 3:h.flags=h.flags&-65537|128;case 0:if(h=g.payload,f=typeof h==`function`?h.call(_,d,f):h,f==null)break a;d=m({},d,f);break a;case 2:Ba=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Xl|=o,e.lanes=o,e.memoizedState=d}}function Xa(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function Za(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=F.T,s={};F.T=s,Fs(e,!1,t,n);try{var c=i(),l=F.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?Ps(e,t,ga(c,r),_u(e)):Ps(e,t,r,_u(e))}catch(n){Ps(e,t,{then:function(){},status:`rejected`,reason:n},_u())}finally{I.p=a,o!==null&&s.types!==null&&(o.types=s.types),F.T=o}}function ws(){}function Ts(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=Es(e).queue;Cs(e,a,t,L,n===null?ws:function(){return Ds(e),n(r)})}function Es(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:L,baseState:L,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Io,lastRenderedState:L},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Io,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function Ds(e){var t=Es(e);t.next===null&&(t=e.alternate.memoizedState),Ps(e,t.next.queue,{},_u())}function Os(){return ta(rp)}function ks(){return Mo().memoizedState}function As(){return Mo().memoizedState}function js(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=_u();e=Ua(n);var r=Wa(t,e,n);r!==null&&(yu(r,t,n),Ga(r,t,n)),t={cache:ca()},e.payload=t;return}t=t.return}}function Ms(e,t,n){var r=_u();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Is(e)?Ls(t,n):(n=ti(e,t,n,r),n!==null&&(yu(n,e,r),U(n,t,r)))}function Ns(e,t,n){Ps(e,t,n,_u())}function Ps(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Is(e))Ls(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,xr(s,o))return ei(e,t,i,0),Bl===null&&$r(),!1}catch{}if(n=ti(e,t,i,r),n!==null)return yu(n,e,r),U(n,t,r),!0}return!1}function Fs(e,t,n,r){if(r={lane:2,revertLane:gd(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Is(e)){if(t)throw Error(i(479))}else t=ti(e,n,r,2),t!==null&&yu(t,e,2)}function Is(e){var t=e.alternate;return e===mo||t!==null&&t===mo}function Ls(e,t){vo=_o=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function U(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Qe(e,n)}}var Rs={readContext:ta,use:Po,useCallback:Co,useContext:Co,useEffect:Co,useImperativeHandle:Co,useLayoutEffect:Co,useInsertionEffect:Co,useMemo:Co,useReducer:Co,useRef:Co,useState:Co,useDebugValue:Co,useDeferredValue:Co,useTransition:Co,useSyncExternalStore:Co,useId:Co,useHostTransitionStatus:Co,useFormState:Co,useActionState:Co,useOptimistic:Co,useMemoCache:Co,useCacheRefresh:Co};Rs.useEffectEvent=Co;var zs={readContext:ta,use:Po,useCallback:function(e,t){return jo().memoizedState=[e,t===void 0?null:t],e},useContext:ta,useEffect:us,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),cs(4194308,4,gs.bind(null,t,e),n)},useLayoutEffect:function(e,t){return cs(4194308,4,e,t)},useInsertionEffect:function(e,t){cs(4,2,e,t)},useMemo:function(e,t){var n=jo();t=t===void 0?null:t;var r=e();if(yo){Fe(!0);try{e()}finally{Fe(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=jo();if(n!==void 0){var i=n(t);if(yo){Fe(!0);try{n(t)}finally{Fe(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=Ms.bind(null,mo,e),[r.memoizedState,e]},useRef:function(e){var t=jo();return e={current:e},t.memoizedState=e},useState:function(e){e=Ko(e);var t=e.queue,n=Ns.bind(null,mo,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:vs,useDeferredValue:function(e,t){return xs(jo(),e,t)},useTransition:function(){var e=Ko(!1);return e=Cs.bind(null,mo,e.queue,!0,!1),jo().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=mo,a=jo();if(Pi){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),Bl===null)throw Error(i(349));Hl&127||Vo(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,us(Uo.bind(null,r,o,e),[e]),r.flags|=2048,os(9,{destroy:void 0},Ho.bind(null,r,o,n,t),null),n},useId:function(){var e=jo(),t=Bl.identifierPrefix;if(Pi){var n=Ei,r=Ti;n=(r&~(1<<32-Ie(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=B++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[at]=t,o[ot]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Bd(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&Mc(t)}}return Lc(t),Nc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&Mc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=oe.current,Vi(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=Mi,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[at]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||Rd(e.nodeValue,n)),e||Ri(t,!0)}else e=Gd(e).createTextNode(r),e[at]=t,t.stateNode=e}return Lc(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=Vi(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[at]=t}else Hi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Lc(t),e=!1}else n=Ui(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(lo(t),t):(lo(t),null);if(t.flags&128)throw Error(i(558))}return Lc(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=Vi(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[at]=t}else Hi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Lc(t),a=!1}else a=Ui(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(lo(t),t):(lo(t),null)}return lo(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Fc(t,t.updateQueue),Lc(t),null);case 4:return le(),e===null&&Od(t.stateNode.containerInfo),Lc(t),null;case 10:return Yi(t.type),Lc(t),null;case 19:if(re(uo),r=t.memoizedState,r===null)return Lc(t),null;if(a=!!(t.flags&128),o=r.rendering,o===null){if(a)Ic(r,!1);else{if(Yl!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=fo(e),o!==null){for(t.flags|=128,Ic(r,!1),e=o.updateQueue,t.updateQueue=e,Fc(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)ui(n,e),n=n.sibling;return z(uo,uo.current&1|2),Pi&&Di(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&we()>au&&(t.flags|=128,a=!0,Ic(r,!1),t.lanes=4194304)}}else{if(!a){if(e=fo(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,Fc(t,e),Ic(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!Pi)return Lc(t),null}else 2*we()-r.renderingStartTime>au&&n!==536870912&&(t.flags|=128,a=!0,Ic(r,!1),t.lanes=4194304)}r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(Lc(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=we(),e.sibling=null,n=uo.current,z(uo,a?n&1|2:n&1),Pi&&Di(t,r.treeForkCount),e);case 22:case 23:return lo(t),no(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(Lc(t),t.subtreeFlags&6&&(t.flags|=8192)):Lc(t),n=t.updateQueue,n!==null&&Fc(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&re(va),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Yi(sa),Lc(t),null;case 25:return null;case 30:return null}throw Error(i(156,t.tag))}function zc(e,t){switch(Ai(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Yi(sa),le(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return de(t),null;case 31:if(t.memoizedState!==null){if(lo(t),t.alternate===null)throw Error(i(340));Hi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(lo(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));Hi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return re(uo),null;case 4:return le(),null;case 10:return Yi(t.type),null;case 22:case 23:return lo(t),no(),e!==null&&re(va),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Yi(sa),null;case 25:return null;default:return null}}function Bc(e,t){switch(Ai(t),t.tag){case 3:Yi(sa),le();break;case 26:case 27:case 5:de(t);break;case 4:le();break;case 31:t.memoizedState!==null&&lo(t);break;case 13:lo(t);break;case 19:re(uo);break;case 10:Yi(t.type);break;case 22:case 23:lo(t),no(),e!==null&&re(va);break;case 24:Yi(sa)}}function Vc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Yu(t,t.return,e)}}function Hc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Yu(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Yu(t,t.return,e)}}function Uc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Za(t,n)}catch(t){Yu(e,e.return,t)}}}function Wc(e,t,n){n.props=Gs(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Yu(e,t,n)}}function Gc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Yu(e,t,n)}}function Kc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null){if(typeof r==`function`)try{r()}catch(n){Yu(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Yu(e,t,n)}else n.current=null}}function qc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Yu(e,e.return,t)}}function Jc(e,t,n){try{var r=e.stateNode;Vd(r,e.type,n,t),r[ot]=t}catch(t){Yu(e,e.return,t)}}function Yc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&nf(e.type)||e.tag===4}function Xc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Yc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&nf(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Zc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=Qt));else if(r!==4&&(r===27&&nf(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(Zc(e,t,n),e=e.sibling;e!==null;)Zc(e,t,n),e=e.sibling}function Qc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&nf(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Qc(e,t,n),e=e.sibling;e!==null;)Qc(e,t,n),e=e.sibling}function $c(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Bd(t,r,n),t[at]=e,t[ot]=n}catch(t){Yu(e,e.return,t)}}var el=!1,tl=!1,nl=!1,rl=typeof WeakSet==`function`?WeakSet:Set,il=null;function al(e,t){if(e=e.containerInfo,Ud=fp,e=Er(e),Dr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var a=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||a!==0&&f.nodeType!==3||(c=s+a),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===a&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(Wd={focusedElem:e,selectionRange:n},fp=!1,il=t;il!==null;)if(t=il,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,il=e;else for(;il!==null;){switch(t=il,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Bd(o,r,n),o[at]=e,vt(o),r=o;break a;case`link`:var s=Kf(`link`,`href`,a).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=wr(s,h),v=wr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,F.T=null,n=pu,pu=null;var o=lu,s=du;if(cu=0,uu=lu=null,du=0,G&6)throw Error(i(331));var c=G;if(G|=4,Fl(o.current),Dl(o,o.current,s,n),G=c,ld(0,!1),Pe&&typeof Pe.onPostCommitFiberRoot==`function`)try{Pe.onPostCommitFiberRoot(Ne,o)}catch{}return!0}finally{I.p=a,F.T=r,Gu(e,t)}}function Ju(e,t,n){t=_i(n,t),t=Zs(e.stateNode,t,2),e=Wa(e,t,2),e!==null&&(Ye(e,2),cd(e))}function Yu(e,t,n){if(e.tag===3)Ju(e,e,n);else for(;t!==null;){if(t.tag===3){Ju(t,e,n);break}if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(su===null||!su.has(r))){e=_i(n,e),n=Qs(2),r=Wa(t,n,2),r!==null&&($s(n,r,t,e),Ye(r,2),cd(r));break}}t=t.return}}function Xu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new zl;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(ql=!0,i.add(n),e=Zu.bind(null,e,t,n),t.then(e,e))}function Zu(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,Bl===e&&(Hl&n)===n&&(Yl===4||Yl===3&&(Hl&62914560)===Hl&&300>we()-ru?!(G&2)&&Eu(e,0):Zl|=n,$l===Hl&&($l=0)),cd(e)}function Qu(e,t){t===0&&(t=qe()),e=ni(e,t),e!==null&&(Ye(e,t),cd(e))}function $u(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),Qu(e,n)}function ed(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),Qu(e,n)}function td(e,t){return be(e,t)}var nd=null,rd=null,id=!1,ad=!1,od=!1,sd=0;function cd(e){e!==rd&&e.next===null&&(rd===null?nd=rd=e:rd=rd.next=e),ad=!0,id||(id=!0,hd())}function ld(e,t){if(!od&&ad){od=!0;do for(var n=!1,r=nd;r!==null;){if(!t){if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-Ie(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,md(r,a))}else a=Hl,a=We(r,r===Bl?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||Ge(r,a)||(n=!0,md(r,a))}r=r.next}while(n);od=!1}}function ud(){dd()}function dd(){ad=id=!1;var e=0;sd!==0&&Xd()&&(e=sd);for(var t=we(),n=null,r=nd;r!==null;){var i=r.next,a=fd(r,t);a===0?(r.next=null,n===null?nd=i:n.next=i,i===null&&(rd=n)):(n=r,(e!==0||a&3)&&(ad=!0)),r=i}cu!==0&&cu!==5||ld(e,!1),sd!==0&&(sd=0)}function fd(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Hd(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function Ef(e,t,n){var r=Tf;if(r&&typeof t==`string`&&t){var i=Lt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),bf.has(i)||(bf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Bd(t,`link`,e),vt(t),r.head.appendChild(t)))}}function Df(e){Sf.D(e),Ef(`dns-prefetch`,e,null)}function Of(e,t){Sf.C(e,t),Ef(`preconnect`,e,t)}function kf(e,t,n){Sf.L(e,t,n);var r=Tf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Lt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Lt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Lt(n.imageSizes)+`"]`)):i+=`[href="`+Lt(e)+`"]`;var a=i;switch(t){case`style`:a=Ff(e);break;case`script`:a=zf(e)}yf.has(a)||(e=m({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),yf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(If(a))||t===`script`&&r.querySelector(Bf(a))||(t=r.createElement(`link`),Bd(t,`link`,e),vt(t),r.head.appendChild(t)))}}function Af(e,t){Sf.m(e,t);var n=Tf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Lt(r)+`"][href="`+Lt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=zf(e)}if(!yf.has(a)&&(e=m({rel:`modulepreload`,href:e},t),yf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Bf(a)))return}r=n.createElement(`link`),Bd(r,`link`,e),vt(r),n.head.appendChild(r)}}}function jf(e,t,n){Sf.S(e,t,n);var r=Tf;if(r&&e){var i=_t(r).hoistableStyles,a=Ff(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(If(a)))s.loading=5;else{e=m({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=yf.get(a))&&Uf(e,n);var c=o=r.createElement(`link`);vt(c),Bd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Hf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Mf(e,t){Sf.X(e,t);var n=Tf;if(n&&e){var r=_t(n).hoistableScripts,i=zf(e),a=r.get(i);a||(a=n.querySelector(Bf(i)),a||(e=m({src:e,async:!0},t),(t=yf.get(i))&&Wf(e,t),a=n.createElement(`script`),vt(a),Bd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Nf(e,t){Sf.M(e,t);var n=Tf;if(n&&e){var r=_t(n).hoistableScripts,i=zf(e),a=r.get(i);a||(a=n.querySelector(Bf(i)),a||(e=m({src:e,async:!0,type:`module`},t),(t=yf.get(i))&&Wf(e,t),a=n.createElement(`script`),vt(a),Bd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Pf(e,t,n,r){var a=(a=oe.current)?xf(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Ff(n.href),n=_t(a).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Ff(n.href);var o=_t(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(If(e)))&&!o._p&&(s.instance=o,s.state.loading=5),yf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},yf.set(e,n),o||Rf(a,e,n,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=zf(n),n=_t(a).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Ff(e){return`href="`+Lt(e)+`"`}function If(e){return`link[rel="stylesheet"][`+e+`]`}function Lf(e){return m({},e,{"data-precedence":e.precedence,precedence:null})}function Rf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Bd(t,`link`,n),vt(t),e.head.appendChild(t))}function zf(e){return`[src="`+Lt(e)+`"]`}function Bf(e){return`script[async]`+e}function Vf(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Lt(n.href)+`"]`);if(r)return t.instance=r,vt(r),r;var a=m({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),vt(r),Bd(r,`style`,a),Hf(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Ff(n.href);var o=e.querySelector(If(a));if(o)return t.state.loading|=4,t.instance=o,vt(o),o;r=Lf(n),(a=yf.get(a))&&Uf(r,a),o=(e.ownerDocument||e).createElement(`link`),vt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Bd(o,`link`,r),t.state.loading|=4,Hf(o,n.precedence,e),t.instance=o;case`script`:return o=zf(n.src),(a=e.querySelector(Bf(o)))?(t.instance=a,vt(a),a):(r=n,(a=yf.get(o))&&(r=m({},n),Wf(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),vt(a),Bd(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Hf(r,n.precedence,e));return t.instance}function Hf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Jf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Yf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Xf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Ff(r.href),a=t.querySelector(If(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=$f.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,vt(a);return}a=t.ownerDocument||t,r=Lf(r),(i=yf.get(i))&&Uf(r,i),a=a.createElement(`link`),vt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Bd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=$f.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Zf=0;function Qf(e,t){return e.stylesheets&&e.count===0&&tp(e,e.stylesheets),0Zf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function $f(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)tp(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var ep=null;function tp(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,ep=new Map,t.forEach(np,e),ep=null,$f.call(e))}function np(e,t){if(!(t.state.loading&4)){var n=ep.get(e);if(n)var r=n.get(null);else{n=new Map,ep.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=g()})),v=l(d(),1),y=_(),b=`modulepreload`,x=function(e){return`/`+e},S={},C=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=x(t,n),t=s(t),t in S)return;S[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:b,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},w=/^(?:[a-z][a-z0-9+.-]*:|[\\/]{2})/i,T=/^[\\/]{2}/;function E(e,t){return t+e.replace(/\\/g,`/`)}var D=`popstate`;function O(e){return typeof e==`object`&&!!e&&`pathname`in e&&`search`in e&&`hash`in e&&`state`in e&&`key`in e}function k(e={}){function t(e,t){let n=t.state?.masked,{pathname:r,search:i,hash:a}=n||e.location;return P(``,{pathname:r,search:i,hash:a},t.state&&t.state.usr||null,t.state&&t.state.key||`default`,n?{pathname:e.location.pathname,search:e.location.search,hash:e.location.hash}:void 0)}function n(e,t){return typeof t==`string`?t:ee(t)}return I(t,n,null,e)}function A(e,t){if(e===!1||e==null)throw Error(t)}function j(e,t){if(!e){typeof console<`u`&&console.warn(t);try{throw Error(t)}catch{}}}function M(){return Math.random().toString(36).substring(2,10)}function N(e,t){return{usr:e.state,key:e.key,idx:t,masked:e.mask?{pathname:e.pathname,search:e.search,hash:e.hash}:void 0}}function P(e,t,n=null,r,i){return{pathname:typeof e==`string`?e:e.pathname,search:``,hash:``,...typeof t==`string`?F(t):t,state:n,key:t&&t.key||r||M(),mask:i}}function ee({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 F(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 I(e,t,n,r={}){let{window:i=document.defaultView,v5Compat:a=!1}=r,o=i.history,s=`POP`,c=null,l=u();l??(l=0,o.replaceState({...o.state,idx:l},``));function u(){return(o.state||{idx:null}).idx}function d(){s=`POP`;let e=u(),t=e==null?null:e-l;l=e,c&&c({action:s,location:h.location,delta:t})}function f(e,t){s=`PUSH`;let r=O(e)?e:P(h.location,e,t);n&&n(r,e),l=u()+1;let d=N(r,l),f=h.createHref(r.mask||r);try{o.pushState(d,``,f)}catch(e){if(e instanceof DOMException&&e.name===`DataCloneError`)throw e;i.location.assign(f)}a&&c&&c({action:s,location:h.location,delta:1})}function p(e,t){s=`REPLACE`;let r=O(e)?e:P(h.location,e,t);n&&n(r,e),l=u();let i=N(r,l),d=h.createHref(r.mask||r);o.replaceState(i,``,d),a&&c&&c({action:s,location:h.location,delta:0})}function m(e){return L(i,e)}let h={get action(){return s},get location(){return e(i,o)},listen(e){if(c)throw Error(`A history only accepts one active listener`);return i.addEventListener(D,d),c=e,()=>{i.removeEventListener(D,d),c=null}},createHref(e){return t(i,e)},createURL:m,encodeLocation(e){let t=m(e);return{pathname:t.pathname,search:t.search,hash:t.hash}},push:f,replace:p,go(e){return o.go(e)}};return h}function L(e,t,n=!1){let r=`http://localhost`;e&&(r=e.location.origin===`null`?e.location.href:e.location.origin),A(r,`No window.location.(origin|href) available to create URL`);let i=typeof t==`string`?t:ee(t);return i=i.replace(/ $/,`%20`),!n&&T.test(i)&&(i=r+i),new URL(i,r)}function R(e,t,n=`/`){return te(e,t,n,!1)}function te(e,t,n,r,i){let a=ye((typeof t==`string`?F(t):t).pathname||`/`,n);if(a==null)return null;let o=i??ne(e),s=null,c=ve(a);for(let e=0;s==null&&e{let c={relativePath:s===void 0?e.path||``:s,caseSensitive:e.caseSensitive===!0,childrenIndex:a,route:e};if(c.relativePath.startsWith(`/`)){if(!c.relativePath.startsWith(r)&&o)return;A(c.relativePath.startsWith(r),`Absolute route path "${c.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),c.relativePath=c.relativePath.slice(r.length)}let l=De([r,c.relativePath]),u=n.concat(c);e.children&&e.children.length>0&&(A(e.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${l}".`),re(e.children,t,u,l,o)),!(e.path==null&&!e.index)&&t.push({path:l,score:fe(l,e.index),routesMeta:u.map((e,t)=>{let[n,r]=_e(e.relativePath,e.caseSensitive,t===u.length-1);return{...e,matcher:n,compiledParams:r}})})};return e.forEach((e,t)=>{if(e.path===``||!e.path?.includes(`?`))a(e,t);else for(let n of z(e.path))a(e,t,!0,n)}),t}function z(e){let t=e.split(`/`);if(t.length===0)return[];let[n,...r]=t,i=n.endsWith(`?`),a=n.replace(/\?$/,``);if(r.length===0)return i?[a,``]:[a];let o=z(r.join(`/`)),s=[];return s.push(...o.map(e=>e===``?a:[a,e].join(`/`))),i&&s.push(...o),s.map(t=>e.startsWith(`/`)&&t===``?`/`:t)}function ie(e){e.sort((e,t)=>e.score===t.score?pe(e.routesMeta.map(e=>e.childrenIndex),t.routesMeta.map(e=>e.childrenIndex)):t.score-e.score)}var ae=/^:[\w-]+$/,oe=3,se=2,ce=1,le=10,ue=-2,de=e=>e===`*`;function fe(e,t){let n=e.split(`/`),r=n.length;return n.some(de)&&(r+=ue),t&&(r+=se),n.filter(e=>!de(e)).reduce((e,t)=>e+(ae.test(t)?oe:t===``?ce:le),r)}function pe(e,t){return e.length===t.length&&e.slice(0,-1).every((e,n)=>e===t[n])?e[e.length-1]-t[t.length-1]:0}function me(e,t,n=!1){let{routesMeta:r}=e,i={},a=`/`,o=[];for(let e=0;e{if(t===`*`){let e=s[r]||``;o=a.slice(0,a.length-e.length).replace(/(.)\/+$/,`$1`)}let i=s[r];return e[t]=n&&!i?void 0:(i||``).replace(/%2F/g,`/`),e},{}),pathname:a,pathnameBase:o,pattern:e}}function _e(e,t=!1,n=!0){j(e===`*`||!e.endsWith(`*`)||e.endsWith(`/*`),`Route path "${e}" will be treated as if it were "${e.replace(/\*$/,`/*`)}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${e.replace(/\*$/,`/*`)}".`);let r=[],i=`^`+e.replace(/\/*\*?$/,``).replace(/^\/*/,`/`).replace(/[\\.*+^${}|()[\]]/g,`\\$&`).replace(/\/:([\w-]+)(\?)?/g,(e,t,n,i,a)=>{if(r.push({paramName:t,isOptional:n!=null}),n){let t=a.charAt(i+e.length);return t&&t!==`/`?`/([^\\/]*)`:`(?:/([^\\/]*))?`}return`/([^\\/]+)`}).replace(/\/([\w-]+)\?(\/|$)/g,`(/$1)?$2`);return e.endsWith(`*`)?(r.push({paramName:`*`}),i+=e===`*`||e===`/*`?`(.*)$`:`(?:\\/(.+)|\\/*)$`):n?i+=`\\/*$`:e!==``&&e!==`/`&&(i+=`(?:(?=\\/|$))`),[new RegExp(i,t?void 0:`i`),r]}function ve(e){try{return e.split(`/`).map(e=>decodeURIComponent(e).replace(/\//g,`%2F`)).join(`/`)}catch(t){return j(!1,`The URL path "${e}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${t}).`),e}}function ye(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 be(e,t=`/`){let{pathname:n,search:r=``,hash:i=``}=typeof e==`string`?F(e):e,a;return n?(n=Ee(n),a=n.startsWith(`/`)?xe(n.substring(1),`/`):xe(n,t)):a=t,{pathname:a,search:Ae(r),hash:je(i)}}function xe(e,t){let n=Oe(t).split(`/`);return e.split(`/`).forEach(e=>{e===`..`?n.length>1&&n.pop():e!==`.`&&n.push(e)}),n.length>1?n.join(`/`):`/`}function Se(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 Ce(e){return e.filter((e,t)=>t===0||e.route.path&&e.route.path.length>0)}function we(e){let t=Ce(e);return t.map((e,n)=>n===t.length-1?e.pathname:e.pathnameBase)}function Te(e,t,n,r=!1){let i;typeof e==`string`?i=F(e):(i={...e},A(!i.pathname||!i.pathname.includes(`?`),Se(`?`,`pathname`,`search`,i)),A(!i.pathname||!i.pathname.includes(`#`),Se(`#`,`pathname`,`hash`,i)),A(!i.search||!i.search.includes(`#`),Se(`#`,`search`,`hash`,i)));let a=e===``||i.pathname===``,o=a?`/`:i.pathname,s;if(o==null)s=n;else{let e=t.length-1;if(!r&&o.startsWith(`..`)){let t=o.split(`/`);for(;t[0]===`..`;)t.shift(),--e;i.pathname=t.join(`/`)}s=e>=0?t[e]:`/`}let c=be(i,s),l=o&&o!==`/`&&o.endsWith(`/`),u=(a||o===`.`)&&n.endsWith(`/`);return!c.pathname.endsWith(`/`)&&(l||u)&&(c.pathname+=`/`),c}var Ee=e=>e.replace(/[\\/]{2,}/g,`/`),De=e=>Ee(e.join(`/`)),Oe=e=>e.replace(/\/+$/,``),ke=e=>Oe(e).replace(/^\/*/,`/`),Ae=e=>!e||e===`?`?``:e.startsWith(`?`)?e:`?`+e,je=e=>!e||e===`#`?``:e.startsWith(`#`)?e:`#`+e,Me=class{constructor(e,t,n,r=!1){this.status=e,this.statusText=t||``,this.internal=r,n instanceof Error?(this.data=n.toString(),this.error=n):this.data=n}};function Ne(e){return e!=null&&typeof e.status==`number`&&typeof e.statusText==`string`&&typeof e.internal==`boolean`&&`data`in e}function Pe(e){return De(e.map(e=>e.route.path).filter(Boolean))||`/`}var Fe=typeof window<`u`&&window.document!==void 0&&window.document.createElement!==void 0;function Ie(e,t){let n=e;if(typeof n!=`string`||!w.test(n))return{absoluteURL:void 0,isExternal:!1,to:n};let r=n,i=!1;if(Fe)try{let e=new URL(window.location.href),r=T.test(n)?new URL(E(n,e.protocol)):new URL(n),a=ye(r.pathname,t);r.origin===e.origin&&a!=null?n=a+r.search+r.hash:i=!0}catch{j(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:r,isExternal:i,to:n}}Object.getOwnPropertyNames(Object.prototype).sort().join(`\0`);var Le=[`POST`,`PUT`,`PATCH`,`DELETE`];new Set(Le);var Re=[`GET`,...Le];new Set(Re);var ze=[`about:`,`blob:`,`chrome:`,`chrome-untrusted:`,`content:`,`data:`,`devtools:`,`file:`,`filesystem:`,`javascript:`];function Be(e){try{return ze.includes(new URL(e).protocol)}catch{return!1}}var Ve=v.createContext(null);Ve.displayName=`DataRouter`;var He=v.createContext(null);He.displayName=`DataRouterState`;var Ue=v.createContext(!1);function We(){return v.useContext(Ue)}var Ge=v.createContext({isTransitioning:!1});Ge.displayName=`ViewTransition`;var Ke=v.createContext(new Map);Ke.displayName=`Fetchers`;var qe=v.createContext(null);qe.displayName=`Await`;var Je=v.createContext(null);Je.displayName=`Navigation`;var Ye=v.createContext(null);Ye.displayName=`Location`;var Xe=v.createContext({outlet:null,matches:[],isDataRoute:!1});Xe.displayName=`Route`;var Ze=v.createContext(null);Ze.displayName=`RouteError`;var Qe=`REACT_ROUTER_ERROR`,$e=`REDIRECT`,et=`ROUTE_ERROR_RESPONSE`;function tt(e){if(e.startsWith(`${Qe}:${$e}:{`))try{let t=JSON.parse(e.slice(28));if(typeof t==`object`&&t&&typeof t.status==`number`&&typeof t.statusText==`string`&&typeof t.location==`string`&&typeof t.reloadDocument==`boolean`&&typeof t.replace==`boolean`)return t}catch{}}function nt(e){if(e.startsWith(`${Qe}:${et}:{`))try{let t=JSON.parse(e.slice(40));if(typeof t==`object`&&t&&typeof t.status==`number`&&typeof t.statusText==`string`)return new Me(t.status,t.statusText,t.data)}catch{}}function rt(e,{relative:t}={}){A(it(),`useHref() may be used only in the context of a component.`);let{basename:n,navigator:r}=v.useContext(Je),{hash:i,pathname:a,search:o}=ft(e,{relative:t}),s=a;return n!==`/`&&(s=a===`/`?n:De([n,a])),r.createHref({pathname:s,search:o,hash:i})}function it(){return v.useContext(Ye)!=null}function at(){return A(it(),`useLocation() may be used only in the context of a component.`),v.useContext(Ye).location}var ot=`You should call navigate() in a React.useEffect(), not when your component is first rendered.`;function st(e){v.useContext(Je).static||v.useLayoutEffect(e)}function ct(){let{isDataRoute:e}=v.useContext(Xe);return e?kt():lt()}function lt(){A(it(),`useNavigate() may be used only in the context of a component.`);let e=v.useContext(Ve),{basename:t,navigator:n}=v.useContext(Je),{matches:r}=v.useContext(Xe),{pathname:i}=at(),a=JSON.stringify(we(r)),o=v.useRef(!1);return st(()=>{o.current=!0}),v.useCallback((r,s={})=>{if(j(o.current,ot),!o.current)return;if(typeof r==`number`){n.go(r);return}let c=Te(r,JSON.parse(a),i,s.relative===`path`);e==null&&t!==`/`&&(c.pathname=c.pathname===`/`?t:De([t,c.pathname])),(s.replace?n.replace:n.push)(c,s.state,s)},[t,n,a,i,e])}var ut=v.createContext(null);function dt(e){let t=v.useContext(Xe).outlet;return v.useMemo(()=>t&&v.createElement(ut.Provider,{value:e},t),[t,e])}function ft(e,{relative:t}={}){let{matches:n}=v.useContext(Xe),{pathname:r}=at(),i=JSON.stringify(we(n));return v.useMemo(()=>Te(e,JSON.parse(i),r,t===`path`),[e,i,r,t])}function pt(e,t){return mt(e,t)}function mt(e,t,n){A(it(),`useRoutes() may be used only in the context of a component.`);let{navigator:r}=v.useContext(Je),{matches:i}=v.useContext(Xe),a=i[i.length-1],o=a?a.params:{},s=a?a.pathname:`/`,c=a?a.pathnameBase:`/`,l=a&&a.route;{let e=l&&l.path||``;jt(s,!l||e.endsWith(`*`)||e.endsWith(`*?`),`You rendered descendant (or called \`useRoutes()\`) at "${s}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. - -Please change the parent to .`)}let u=at(),d;if(t){let e=typeof t==`string`?F(t):t;A(c===`/`||e.pathname?.startsWith(c),`When overriding the location using \`\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${c}" but pathname "${e.pathname}" was given in the \`location\` prop.`),d=e}else d=u;let f=d.pathname||`/`,p=f;if(c!==`/`){let e=c.replace(/^\//,``).split(`/`);p=`/`+f.replace(/^\//,``).split(`/`).slice(e.length).join(`/`)}let m=n&&n.state.matches.length?n.state.matches.map(e=>Object.assign(e,{route:n.manifest[e.route.id]||e.route})):R(e,{pathname:p});j(l||m!=null,`No routes matched location "${d.pathname}${d.search}${d.hash}" `),j(m==null||m[m.length-1].route.element!==void 0||m[m.length-1].route.Component!==void 0||m[m.length-1].route.lazy!==void 0,`Matched leaf route at location "${d.pathname}${d.search}${d.hash}" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.`);let h=xt(m&&m.map(e=>Object.assign({},e,{params:Object.assign({},o,e.params),pathname:De([c,r.encodeLocation?r.encodeLocation(e.pathname.replace(/%/g,`%25`).replace(/\?/g,`%3F`).replace(/#/g,`%23`)).pathname:e.pathname]),pathnameBase:e.pathnameBase===`/`?c:De([c,r.encodeLocation?r.encodeLocation(e.pathnameBase.replace(/%/g,`%25`).replace(/\?/g,`%3F`).replace(/#/g,`%23`)).pathname:e.pathnameBase])})),i,n);return t&&h?v.createElement(Ye.Provider,{value:{location:{pathname:`/`,search:``,hash:``,state:null,key:`default`,mask:void 0,...d},navigationType:`POP`}},h):h}function ht(){let e=Ot(),t=Ne(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,r=`rgba(200,200,200, 0.5)`,i={padding:`0.5rem`,backgroundColor:r},a={padding:`2px 4px`,backgroundColor:r},o=null;return console.error(`Error handled by React Router default ErrorBoundary:`,e),o=v.createElement(v.Fragment,null,v.createElement(`p`,null,`💿 Hey developer 👋`),v.createElement(`p`,null,`You can provide a way better UX than this when your app throws errors by providing your own `,v.createElement(`code`,{style:a},`ErrorBoundary`),` or`,` `,v.createElement(`code`,{style:a},`errorElement`),` prop on your route.`)),v.createElement(v.Fragment,null,v.createElement(`h2`,null,`Unexpected Application Error!`),v.createElement(`h3`,{style:{fontStyle:`italic`}},t),n?v.createElement(`pre`,{style:i},n):null,o)}var gt=v.createElement(ht,null),_t=class extends v.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!==`idle`&&e.revalidation===`idle`?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error===void 0?t.error:e.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){this.props.onError?this.props.onError(e,t):console.error(`React Router caught the following error during render`,e)}render(){let e=this.state.error;if(this.context&&typeof e==`object`&&e&&`digest`in e&&typeof e.digest==`string`){let t=nt(e.digest);t&&(e=t)}let t=e===void 0?this.props.children:v.createElement(Xe.Provider,{value:this.props.routeContext},v.createElement(Ze.Provider,{value:e,children:this.props.component}));return this.context?v.createElement(yt,{error:e},t):t}};_t.contextType=Ue;var vt=new WeakMap;function yt({children:e,error:t}){let{basename:n}=v.useContext(Je);if(typeof t==`object`&&t&&`digest`in t&&typeof t.digest==`string`){let e=tt(t.digest);if(e){let r=vt.get(t);if(r)throw r;let i=Ie(e.location,n),a=i.absoluteURL||i.to;if(Be(a))throw Error(`Invalid redirect location`);if(Fe&&!vt.get(t)){if(i.isExternal||e.reloadDocument)window.location.href=a;else{let n=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(i.to,{replace:e.replace}));throw vt.set(t,n),n}}return v.createElement(`meta`,{httpEquiv:`refresh`,content:`0;url=${a}`})}}return e}function bt({routeContext:e,match:t,children:n}){let r=v.useContext(Ve);return r&&r.static&&r.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=t.route.id),v.createElement(Xe.Provider,{value:e},n)}function xt(e,t=[],n){let r=n?.state;if(e==null){if(!r)return null;if(r.errors)e=r.matches;else if(t.length===0&&!r.initialized&&r.matches.length>0)e=r.matches;else return null}let i=e,a=r?.errors;if(a!=null){let e=i.findIndex(e=>e.route.id&&a?.[e.route.id]!==void 0);A(e>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(a).join(`,`)}`),i=i.slice(0,Math.min(i.length,e+1))}let o=!1,s=-1;if(n&&r){o=r.renderFallback;for(let e=0;e=0?i.slice(0,s+1):[i[0]];break}}}}let c=n?.onError,l=r&&c?(e,t)=>{c(e,{location:r.location,params:r.matches?.[0]?.params??{},pattern:Pe(r.matches),errorInfo:t})}:void 0;return i.reduceRight((e,n,c)=>{let u,d=!1,f=null,p=null;r&&(u=a&&n.route.id?a[n.route.id]:void 0,f=n.route.errorElement||gt,o&&(s<0&&c===0?(jt(`route-fallback`,!1,"No `HydrateFallback` element provided to render during initial hydration"),d=!0,p=null):s===c&&(d=!0,p=n.route.hydrateFallbackElement||null)));let m=t.concat(i.slice(0,c+1)),h=()=>{let t;return t=u?f:d?p:n.route.Component?v.createElement(n.route.Component,null):n.route.element?n.route.element:e,v.createElement(bt,{match:n,routeContext:{outlet:e,matches:m,isDataRoute:r!=null},children:t})};return r&&(n.route.ErrorBoundary||n.route.errorElement||c===0)?v.createElement(_t,{location:r.location,revalidation:r.revalidation,component:f,error:u,children:h(),routeContext:{outlet:null,matches:m,isDataRoute:!0},onError:l}):h()},null)}function St(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Ct(e){let t=v.useContext(Ve);return A(t,St(e)),t}function wt(e){let t=v.useContext(He);return A(t,St(e)),t}function Tt(e){let t=v.useContext(Xe);return A(t,St(e)),t}function Et(e){let t=Tt(e),n=t.matches[t.matches.length-1];return A(n.route.id,`${e} can only be used on routes that contain a unique "id"`),n.route.id}function Dt(){return Et(`useRouteId`)}function Ot(){let e=v.useContext(Ze),t=wt(`useRouteError`),n=Et(`useRouteError`);return e===void 0?t.errors?.[n]:e}function kt(){let{router:e}=Ct(`useNavigate`),t=Et(`useNavigate`),n=v.useRef(!1);return st(()=>{n.current=!0}),v.useCallback(async(r,i={})=>{j(n.current,ot),n.current&&(typeof r==`number`?await e.navigate(r):await e.navigate(r,{fromRouteId:t,...i}))},[e,t])}var At={};function jt(e,t,n){!t&&!At[e]&&(At[e]=!0,j(!1,n))}v.memo(Mt);function Mt({routes:e,manifest:t,future:n,state:r,isStatic:i,onError:a}){return mt(e,void 0,{manifest:t,state:r,isStatic:i,onError:a,future:n})}function Nt({to:e,replace:t,state:n,relative:r}){A(it(),` may be used only in the context of a component.`);let{static:i}=v.useContext(Je);j(!i,` 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:a}=v.useContext(Xe),{pathname:o}=at(),s=ct(),c=Te(e,we(a),o,r===`path`),l=JSON.stringify(c);return v.useEffect(()=>{s(JSON.parse(l),{replace:t,state:n,relative:r})},[s,l,r,t,n]),null}function Pt(e){return dt(e.context)}function Ft(e){A(!1,`A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .`)}function It({basename:e=`/`,children:t=null,location:n,navigationType:r=`POP`,navigator:i,static:a=!1,useTransitions:o}){A(!it(),`You cannot render a inside another . You should never have more than one in your app.`);let s=e.replace(/^\/*/,`/`),c=v.useMemo(()=>({basename:s,navigator:i,static:a,useTransitions:o,future:{}}),[s,i,a,o]);typeof n==`string`&&(n=F(n));let{pathname:l=`/`,search:u=``,hash:d=``,state:f=null,key:p=`default`,mask:m}=n,h=v.useMemo(()=>{let e=ye(l,s);return e==null?null:{location:{pathname:e,search:u,hash:d,state:f,key:p,mask:m},navigationType:r}},[s,l,u,d,f,p,r,m]);return j(h!=null,` is not able to match the URL "${l}${u}${d}" because it does not start with the basename, so the won't render anything.`),h==null?null:v.createElement(Je.Provider,{value:c},v.createElement(Ye.Provider,{children:t,value:h}))}function Lt({children:e,location:t}){return pt(Rt(e),t)}v.Component;function Rt(e,t=[]){let n=[];return v.Children.forEach(e,(e,r)=>{if(!v.isValidElement(e))return;let i=[...t,r];if(e.type===v.Fragment){n.push.apply(n,Rt(e.props.children,i));return}A(e.type===Ft,`[${typeof e.type==`string`?e.type:e.type.name}] is not a component. All component children of must be a or `),A(!e.props.index||!e.props.children,`An index route cannot have child routes.`);let a={id:e.props.id||i.join(`-`),caseSensitive:e.props.caseSensitive,element:e.props.element,Component:e.props.Component,index:e.props.index,path:e.props.path,middleware:e.props.middleware,loader:e.props.loader,action:e.props.action,hydrateFallbackElement:e.props.hydrateFallbackElement,HydrateFallback:e.props.HydrateFallback,errorElement:e.props.errorElement,ErrorBoundary:e.props.ErrorBoundary,hasErrorBoundary:e.props.hasErrorBoundary===!0||e.props.ErrorBoundary!=null||e.props.errorElement!=null,shouldRevalidate:e.props.shouldRevalidate,handle:e.props.handle,lazy:e.props.lazy};e.props.children&&(a.children=Rt(e.props.children,i)),n.push(a)}),n}var zt=`get`,Bt=`application/x-www-form-urlencoded`;function Vt(e){return typeof HTMLElement<`u`&&e instanceof HTMLElement}function Ht(e){return Vt(e)&&e.tagName.toLowerCase()===`button`}function Ut(e){return Vt(e)&&e.tagName.toLowerCase()===`form`}function Wt(e){return Vt(e)&&e.tagName.toLowerCase()===`input`}function Gt(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function Kt(e,t){return e.button===0&&(!t||t===`_self`)&&!Gt(e)}var qt=null;function Jt(){if(qt===null)try{new FormData(document.createElement(`form`),0),qt=!1}catch{qt=!0}return qt}var Yt=new Set([`application/x-www-form-urlencoded`,`multipart/form-data`,`text/plain`]);function Xt(e){return e!=null&&!Yt.has(e)?(j(!1,`"${e}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${Bt}"`),null):e}function Zt(e,t){let n,r,i,a,o;if(Ut(e)){let o=e.getAttribute(`action`);r=o?ye(o,t):null,n=e.getAttribute(`method`)||zt,i=Xt(e.getAttribute(`enctype`))||Bt,a=new FormData(e)}else if(Ht(e)||Wt(e)&&(e.type===`submit`||e.type===`image`)){let o=e.form;if(o==null)throw Error(`Cannot submit a