diff --git a/Taskfile.yml b/Taskfile.yml
index 62db924..d8f24a8 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -38,9 +38,9 @@ tasks:
- task --list
build:
- desc: Build the full incident-commander binary with embedded UI
- deps:
- - go:build
+ desc: Build standalone plugin modules
+ cmds:
+ - task -d opensearch build
clean:
desc: Remove build artifacts and Task checksums
@@ -53,6 +53,7 @@ tasks:
tailwind-asset:
desc: Download the vendored Tailwind script used by the OIDC static page
cmds:
+ - mkdir -p auth/oidc/static
- curl -sL "https://cdn.tailwindcss.com/{{.TAILWIND_VERSION}}" -o {{.TAILWIND_JS}}
generates:
- "{{.TAILWIND_JS}}"
diff --git a/opensearch/Plugin.yaml b/opensearch/Plugin.yaml
new file mode 100644
index 0000000..86ed512
--- /dev/null
+++ b/opensearch/Plugin.yaml
@@ -0,0 +1,24 @@
+apiVersion: mission-control.flanksource.com/v1
+kind: Plugin
+metadata:
+ name: opensearch
+spec:
+ source: opensearch
+ version: "0.1.0"
+ selector:
+ types:
+ - MissionControl::Connection
+ - OpenSearch::Cluster
+ - OpenSearch::Index
+ - Elasticsearch::Cluster
+ - Elasticsearch::Index
+ connections:
+ opensearch: {}
+
+ # Optional plugin properties:
+ # defaultProfile: jaeger
+ # index: jaeger-span*
+ # profilesYaml: |
+ # custom:
+ # imports: [otel]
+ # index: traces-*
diff --git a/opensearch/Taskfile.yml b/opensearch/Taskfile.yml
new file mode 100644
index 0000000..c18616c
--- /dev/null
+++ b/opensearch/Taskfile.yml
@@ -0,0 +1,80 @@
+version: "3"
+
+vars:
+ PLUGIN_NAME: opensearch
+ VERSION:
+ sh: git describe --tags --always --dirty 2>/dev/null || echo dev
+ BUILD_DATE:
+ sh: date -u "+%Y-%m-%d %H:%M:%S"
+ PLUGIN_PATH:
+ sh: echo "${MISSION_CONTROL_PLUGIN_PATH:-$HOME/.mission-control/plugins}"
+
+tasks:
+ ui:install:
+ desc: Install pnpm dependencies for the OpenSearch plugin UI
+ dir: ui-src
+ cmds:
+ - PATH="/usr/local/opt/node/bin:$PATH" CI=true pnpm install --no-frozen-lockfile --prefer-offline
+ sources:
+ - package.json
+ status:
+ - test -f node_modules/.modules.yaml
+ - test node_modules/.modules.yaml -nt package.json
+
+ ui:build:
+ desc: Build the plugin UI bundle into ./ui
+ dir: ui-src
+ deps: [ui:install]
+ env:
+ PLUGIN_VERSION: "{{.VERSION}}"
+ PLUGIN_BUILD_DATE: "{{.BUILD_DATE}}"
+ cmds:
+ - PATH="/usr/local/opt/node/bin:$PATH" pnpm run build
+ sources:
+ - src/**/*.ts
+ - src/**/*.tsx
+ - src/**/*.css
+ - index.html
+ - package.json
+ - tsconfig.json
+ - vite.config.ts
+ generates:
+ - ../ui/index.html
+
+ generate:
+ desc: Regenerate ui_checksum.go from the built UI bundle
+ deps: [ui:build]
+ cmds:
+ - go generate .
+ sources:
+ - ui/**
+ - internal/gen-checksum/main.go
+ generates:
+ - ui_checksum.go
+
+ test:
+ desc: Run plugin unit tests
+ cmds:
+ - go test .
+
+ build:
+ desc: Build and install the plugin binary into $MISSION_CONTROL_PLUGIN_PATH
+ deps: [generate]
+ cmds:
+ - mkdir -p {{.PLUGIN_PATH}}
+ - >-
+ go build -o {{.PLUGIN_PATH}}/{{.PLUGIN_NAME}}
+ -ldflags "-X 'main.Version={{.VERSION}}' -X 'main.BuildDate={{.BUILD_DATE}}'"
+ .
+ - echo "Installed {{.PLUGIN_PATH}}/{{.PLUGIN_NAME}} version={{.VERSION}} built={{.BUILD_DATE}}"
+ sources:
+ - ./*.go
+ - profiles/**
+ - internal/**/*.go
+ - ui/**
+ - ui_checksum.go
+ - ../../plugin/**/*.go
+ - ../../go.mod
+ - ../../go.sum
+ generates:
+ - "{{.PLUGIN_PATH}}/{{.PLUGIN_NAME}}"
diff --git a/opensearch/client.go b/opensearch/client.go
new file mode 100644
index 0000000..51d5178
--- /dev/null
+++ b/opensearch/client.go
@@ -0,0 +1,172 @@
+package main
+
+import (
+ "bytes"
+ "context"
+ "crypto/tls"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+ "time"
+
+ "github.com/flanksource/incident-commander/plugin/sdk"
+)
+
+type resolvedOpenSearch struct {
+ URLs []string
+ Username string
+ Password string
+ Index string
+ InsecureSkipVerify bool
+}
+
+type openSearchClient struct {
+ conn resolvedOpenSearch
+ client *http.Client
+}
+
+func resolveOpenSearch(ctx context.Context, host sdk.HostClient, configItemID string) (resolvedOpenSearch, error) {
+ if host == nil {
+ return resolvedOpenSearch{}, fmt.Errorf("no host client available")
+ }
+ conn, err := host.GetConnection(ctx, "opensearch", configItemID)
+ if err != nil {
+ return resolvedOpenSearch{}, fmt.Errorf("get opensearch connection: %w", err)
+ }
+ if conn == nil {
+ return resolvedOpenSearch{}, fmt.Errorf("host returned no opensearch connection")
+ }
+ out := resolvedOpenSearch{
+ Username: conn.Username,
+ Password: conn.Password,
+ }
+ if conn.Url != "" {
+ out.URLs = append(out.URLs, conn.Url)
+ }
+ if conn.Properties != nil {
+ props := conn.Properties.AsMap()
+ if raw, ok := props["urls"].(string); ok {
+ for _, part := range strings.Split(raw, ",") {
+ if trimmed := strings.TrimSpace(part); trimmed != "" {
+ out.URLs = append(out.URLs, trimmed)
+ }
+ }
+ }
+ if values, ok := props["urls"].([]any); ok {
+ for _, value := range values {
+ if s, ok := value.(string); ok && strings.TrimSpace(s) != "" {
+ out.URLs = append(out.URLs, strings.TrimSpace(s))
+ }
+ }
+ }
+ if index, ok := props["index"].(string); ok {
+ out.Index = index
+ }
+ if insecure, ok := props["insecureSkipVerify"].(bool); ok {
+ out.InsecureSkipVerify = insecure
+ }
+ if insecure, ok := props["insecure_tls"].(bool); ok {
+ out.InsecureSkipVerify = insecure
+ }
+ }
+ out.URLs = uniqueStrings(out.URLs)
+ if len(out.URLs) == 0 {
+ return resolvedOpenSearch{}, fmt.Errorf("opensearch connection has no urls")
+ }
+ return out, nil
+}
+
+func newOpenSearchClient(conn resolvedOpenSearch) *openSearchClient {
+ transport := http.DefaultTransport.(*http.Transport).Clone()
+ if conn.InsecureSkipVerify {
+ transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
+ }
+ return &openSearchClient{
+ conn: conn,
+ client: &http.Client{
+ Timeout: 60 * time.Second,
+ Transport: transport,
+ },
+ }
+}
+
+func (c *openSearchClient) Check(ctx context.Context) error {
+ req, err := http.NewRequestWithContext(ctx, http.MethodGet, strings.TrimRight(c.conn.URLs[0], "/"), nil)
+ if err != nil {
+ return err
+ }
+ c.authorize(req)
+ resp, err := c.client.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode >= 400 {
+ body, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))
+ return fmt.Errorf("opensearch returned %s: %s", resp.Status, strings.TrimSpace(string(body)))
+ }
+ return nil
+}
+
+func (c *openSearchClient) Search(ctx context.Context, index string, limit int, query map[string]any) (map[string]any, error) {
+ if limit <= 0 {
+ limit = 100
+ }
+ body, err := json.Marshal(query)
+ if err != nil {
+ return nil, fmt.Errorf("marshal query: %w", err)
+ }
+ base := strings.TrimRight(c.conn.URLs[0], "/")
+ url := base + "/" + strings.Trim(index, "/") + "/_search"
+ req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
+ if err != nil {
+ return nil, err
+ }
+ q := req.URL.Query()
+ q.Set("size", fmt.Sprintf("%d", limit))
+ req.URL.RawQuery = q.Encode()
+ req.Header.Set("Content-Type", "application/json")
+ c.authorize(req)
+ resp, err := c.client.Do(req)
+ if err != nil {
+ return nil, fmt.Errorf("execute search: %w", err)
+ }
+ defer resp.Body.Close()
+ respBody, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return nil, fmt.Errorf("read search response: %w", err)
+ }
+ if resp.StatusCode >= 400 {
+ return nil, fmt.Errorf("opensearch search returned %s: %s", resp.Status, strings.TrimSpace(string(respBody)))
+ }
+ var result map[string]any
+ if err := json.Unmarshal(respBody, &result); err != nil {
+ return nil, fmt.Errorf("decode search response: %w", err)
+ }
+ return result, nil
+}
+
+func (c *openSearchClient) authorize(req *http.Request) {
+ if c.conn.Username != "" || c.conn.Password != "" {
+ req.SetBasicAuth(c.conn.Username, c.conn.Password)
+ }
+}
+
+func uniqueStrings(values []string) []string {
+ seen := map[string]struct{}{}
+ out := make([]string, 0, len(values))
+ for _, value := range values {
+ value = strings.TrimSpace(value)
+ if value == "" {
+ continue
+ }
+ if _, ok := seen[value]; ok {
+ continue
+ }
+ seen[value] = struct{}{}
+ out = append(out, value)
+ }
+ return out
+}
diff --git a/opensearch/go.mod b/opensearch/go.mod
new file mode 100644
index 0000000..a2e4f99
--- /dev/null
+++ b/opensearch/go.mod
@@ -0,0 +1,27 @@
+module github.com/flanksource/mission-control-plugins/opensearch
+
+go 1.26.1
+
+require (
+ github.com/flanksource/incident-commander v0.0.1747
+ gopkg.in/yaml.v3 v3.0.1
+)
+
+
+require (
+ github.com/fatih/color v1.18.0 // indirect
+ github.com/golang/protobuf v1.5.4 // indirect
+ github.com/hashicorp/go-hclog v1.6.3 // indirect
+ github.com/hashicorp/go-plugin v1.8.0 // indirect
+ github.com/hashicorp/yamux v0.1.2 // indirect
+ github.com/mattn/go-colorable v0.1.14 // indirect
+ github.com/mattn/go-isatty v0.0.20 // indirect
+ github.com/oklog/run v1.1.0 // indirect
+ golang.org/x/net v0.53.0 // indirect
+ golang.org/x/sys v0.43.0 // indirect
+ golang.org/x/text v0.36.0 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect
+ google.golang.org/grpc v1.80.0 // indirect
+ google.golang.org/protobuf v1.36.11 // indirect
+ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
+)
diff --git a/opensearch/go.sum b/opensearch/go.sum
new file mode 100644
index 0000000..e035ed9
--- /dev/null
+++ b/opensearch/go.sum
@@ -0,0 +1,110 @@
+github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
+github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
+github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
+github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
+github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
+github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
+github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc=
+github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
+github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
+github.com/hashicorp/go-plugin v1.8.0 h1:ie8S6RRY8RvB2usYZv+AAZ/wBvx2AU5p5QeP5j/FORs=
+github.com/hashicorp/go-plugin v1.8.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
+github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
+github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=
+github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=
+github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
+github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
+github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
+github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
+github.com/onsi/ginkgo/v2 v2.28.1 h1:S4hj+HbZp40fNKuLUQOYLDgZLwNUVn19N3Atb98NCyI=
+github.com/onsi/ginkgo/v2 v2.28.1/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE=
+github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=
+github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
+github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
+github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
+go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
+go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
+go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
+go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
+go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
+go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
+go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
+go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
+go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
+go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
+go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
+go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
+go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
+go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
+golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
+golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
+golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
+golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
+golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
+golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
+golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
+golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
+golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
+golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
+golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
+gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
+gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
+google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
+google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
+google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
+google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/opensearch/http.go b/opensearch/http.go
new file mode 100644
index 0000000..491c6db
--- /dev/null
+++ b/opensearch/http.go
@@ -0,0 +1,18 @@
+package main
+
+import (
+ "net/http"
+
+ "github.com/flanksource/incident-commander/plugin/sdk"
+)
+
+func (p *OpenSearchPlugin) HTTPHandler() http.Handler {
+ mux := http.NewServeMux()
+ mux.Handle("/version", sdk.VersionHandler(sdk.BuildInfo{
+ Name: pluginName,
+ Version: Version,
+ BuildDate: BuildDate,
+ UIChecksum: uiChecksum,
+ }))
+ return mux
+}
diff --git a/opensearch/internal/gen-checksum/main.go b/opensearch/internal/gen-checksum/main.go
new file mode 100644
index 0000000..a124b0f
--- /dev/null
+++ b/opensearch/internal/gen-checksum/main.go
@@ -0,0 +1,70 @@
+package main
+
+import (
+ "crypto/sha256"
+ "encoding/hex"
+ "fmt"
+ "io"
+ "io/fs"
+ "os"
+ "path/filepath"
+ "sort"
+)
+
+const (
+ outputPath = "ui_checksum.go"
+ uiDir = "ui"
+)
+
+func main() {
+ files, err := walk(uiDir)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "gen-checksum: walk %s: %v\n", uiDir, err)
+ os.Exit(1)
+ }
+ hasher := sha256.New()
+ for _, path := range files {
+ f, err := os.Open(path)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "gen-checksum: open %s: %v\n", path, err)
+ os.Exit(1)
+ }
+ fmt.Fprintf(hasher, "%s\x00", path)
+ if _, err := io.Copy(hasher, f); err != nil {
+ f.Close()
+ fmt.Fprintf(os.Stderr, "gen-checksum: read %s: %v\n", path, err)
+ os.Exit(1)
+ }
+ f.Close()
+ }
+ sum := hex.EncodeToString(hasher.Sum(nil))
+ contents := fmt.Sprintf(`// Code generated by plugins/opensearch/internal/gen-checksum. DO NOT EDIT.
+
+package main
+
+const uiChecksum = %q
+`, sum)
+ if err := os.WriteFile(outputPath, []byte(contents), 0o644); err != nil {
+ fmt.Fprintf(os.Stderr, "gen-checksum: write %s: %v\n", outputPath, err)
+ os.Exit(1)
+ }
+}
+
+func walk(root string) ([]string, error) {
+ var out []string
+ err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+ if d.IsDir() {
+ return nil
+ }
+ out = append(out, path)
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+ sort.Strings(out)
+ return out, nil
+}
diff --git a/opensearch/main.go b/opensearch/main.go
new file mode 100644
index 0000000..611fc47
--- /dev/null
+++ b/opensearch/main.go
@@ -0,0 +1,125 @@
+// OpenSearch plugin: generic profile-based trace querying for Mission Control.
+//
+// Build: task -d plugins/opensearch build
+// Apply: kubectl apply -f plugins/opensearch/Plugin.yaml
+package main
+
+import (
+ "context"
+ "embed"
+ "io/fs"
+
+ pluginpb "github.com/flanksource/incident-commander/plugin/proto"
+ "github.com/flanksource/incident-commander/plugin/sdk"
+)
+
+const (
+ OpProfilesList = "profiles-list"
+ OpTraceQuery = "trace-query"
+ OpQueryPreview = "query-preview"
+ OpConnectionCheck = "connection-check"
+ pluginName = "opensearch"
+)
+
+//go:generate go run ./internal/gen-checksum
+
+//go:embed all:ui
+var uiAssets embed.FS
+
+var (
+ Version = ""
+ BuildDate = ""
+)
+
+func main() {
+ sub, err := fs.Sub(uiAssets, "ui")
+ if err != nil {
+ panic(err)
+ }
+ sdk.Serve(newPlugin(), sdk.WithStaticAssets(sub))
+}
+
+type OpenSearchPlugin struct {
+ settings PluginSettings
+}
+
+type PluginSettings struct {
+ DefaultProfile string
+ Index string
+ Profiles map[string]TracingProfile
+}
+
+func defaultSettings() PluginSettings {
+ return PluginSettings{
+ DefaultProfile: "jaeger",
+ Profiles: map[string]TracingProfile{},
+ }
+}
+
+func newPlugin() *OpenSearchPlugin {
+ return &OpenSearchPlugin{settings: defaultSettings()}
+}
+
+func (p *OpenSearchPlugin) Manifest() *pluginpb.PluginManifest {
+ return &pluginpb.PluginManifest{
+ Name: pluginName,
+ Version: sdk.FormatVersion(Version, BuildDate, uiChecksum),
+ Description: "Query OpenSearch trace indexes through profile-driven filters and table views.",
+ Capabilities: []string{"tabs", "operations"},
+ Tabs: []*pluginpb.TabSpec{
+ {Name: "OpenSearch", Icon: "lucide:search", Path: "/", Scope: "config"},
+ },
+ Operations: operationDefs(),
+ }
+}
+
+func (p *OpenSearchPlugin) Configure(_ context.Context, settings map[string]any) error {
+ next := p.settings
+ if next.DefaultProfile == "" {
+ next = defaultSettings()
+ }
+ if v, ok := settings["defaultProfile"].(string); ok && v != "" {
+ next.DefaultProfile = v
+ }
+ if v, ok := settings["index"].(string); ok && v != "" {
+ next.Index = v
+ }
+ if v, ok := settings["profilesYaml"].(string); ok && v != "" {
+ profiles, err := parseProfilesYAML([]byte(v))
+ if err != nil {
+ return err
+ }
+ next.Profiles = profiles
+ }
+ p.settings = next
+ return nil
+}
+
+func (p *OpenSearchPlugin) Operations() []sdk.Operation {
+ handlers := map[string]func(context.Context, sdk.InvokeCtx) (any, error){
+ OpProfilesList: p.profilesList,
+ OpTraceQuery: p.traceQuery,
+ OpQueryPreview: p.queryPreview,
+ OpConnectionCheck: p.connectionCheck,
+ }
+ defs := operationDefs()
+ out := make([]sdk.Operation, 0, len(defs))
+ for _, d := range defs {
+ if h, ok := handlers[d.Name]; ok {
+ out = append(out, sdk.Operation{Def: d, Handler: h})
+ }
+ }
+ return out
+}
+
+func operationDefs() []*pluginpb.OperationDef {
+ mk := func(name, desc string) *pluginpb.OperationDef {
+ return &pluginpb.OperationDef{Name: name, Description: desc, Scope: "config", ResultMime: sdk.ClickyResultMimeType}
+ }
+ return []*pluginpb.OperationDef{
+ mk(OpProfilesList, "List resolved OpenSearch tracing profiles."),
+ mk(OpTraceQuery, "Run a profile-based OpenSearch trace query."),
+ mk(OpQueryPreview, "Render the OpenSearch query body without executing it."),
+ mk(OpConnectionCheck, "Verify the resolved OpenSearch connection responds."),
+ }
+}
diff --git a/opensearch/ops.go b/opensearch/ops.go
new file mode 100644
index 0000000..df34393
--- /dev/null
+++ b/opensearch/ops.go
@@ -0,0 +1,102 @@
+package main
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+
+ "github.com/flanksource/incident-commander/plugin/sdk"
+)
+
+type TraceQueryRequest struct {
+ Profile string `json:"profile"`
+ From string `json:"from,omitempty"`
+ To string `json:"to,omitempty"`
+ Limit int `json:"limit,omitempty"`
+ Params map[string]any `json:"params,omitempty"`
+}
+
+type ConnectionCheckResult struct {
+ OK bool `json:"ok"`
+ URLs []string `json:"urls"`
+ Index string `json:"index,omitempty"`
+ Message string `json:"message,omitempty"`
+}
+
+func (p *OpenSearchPlugin) profilesList(_ context.Context, _ sdk.InvokeCtx) (any, error) {
+ return p.settings.profileSummaries()
+}
+
+func (p *OpenSearchPlugin) queryPreview(_ context.Context, req sdk.InvokeCtx) (any, error) {
+ params, profile, err := p.decodeQuery(req.ParamsJSON)
+ if err != nil {
+ return nil, err
+ }
+ return buildQueryPreview(profile, params)
+}
+
+func (p *OpenSearchPlugin) traceQuery(ctx context.Context, req sdk.InvokeCtx) (any, error) {
+ params, profile, err := p.decodeQuery(req.ParamsJSON)
+ if err != nil {
+ return nil, err
+ }
+ preview, err := buildQueryPreview(profile, params)
+ if err != nil {
+ return nil, err
+ }
+ conn, err := resolveOpenSearch(ctx, req.Host, req.ConfigItemID)
+ if err != nil {
+ return nil, err
+ }
+ if profile.Index == "" {
+ profile.Index = conn.Index
+ }
+ if profile.Index == "" {
+ return nil, fmt.Errorf("no OpenSearch index configured for profile %q", profile.Name)
+ }
+ client := newOpenSearchClient(conn)
+ raw, err := client.Search(ctx, profile.Index, preview.Request.Limit, preview.Request.Query)
+ if err != nil {
+ return nil, err
+ }
+ return parseSearchResult(raw, profile), nil
+}
+
+func (p *OpenSearchPlugin) connectionCheck(ctx context.Context, req sdk.InvokeCtx) (any, error) {
+ conn, err := resolveOpenSearch(ctx, req.Host, req.ConfigItemID)
+ if err != nil {
+ return nil, err
+ }
+ err = newOpenSearchClient(conn).Check(ctx)
+ result := ConnectionCheckResult{
+ OK: err == nil,
+ URLs: conn.URLs,
+ Index: conn.Index,
+ }
+ if err != nil {
+ result.Message = err.Error()
+ return result, err
+ }
+ result.Message = "connected"
+ return result, nil
+}
+
+func (p *OpenSearchPlugin) decodeQuery(data []byte) (TraceQueryRequest, TracingProfile, error) {
+ var req TraceQueryRequest
+ if len(data) > 0 {
+ if err := json.Unmarshal(data, &req); err != nil {
+ return TraceQueryRequest{}, TracingProfile{}, fmt.Errorf("decode params: %w", err)
+ }
+ }
+ if req.Params == nil {
+ req.Params = map[string]any{}
+ }
+ profile, err := p.settings.resolveProfile(req.Profile)
+ if err != nil {
+ return TraceQueryRequest{}, TracingProfile{}, err
+ }
+ if req.Profile == "" {
+ req.Profile = profile.Name
+ }
+ return req, profile, nil
+}
diff --git a/opensearch/parser.go b/opensearch/parser.go
new file mode 100644
index 0000000..093fd78
--- /dev/null
+++ b/opensearch/parser.go
@@ -0,0 +1,351 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "math"
+ "strconv"
+ "strings"
+ "time"
+)
+
+type TraceResult struct {
+ Profile string `json:"profile"`
+ Index string `json:"index"`
+ Total int `json:"total"`
+ Traces []Trace `json:"traces"`
+}
+
+type Trace struct {
+ Timestamp string `json:"timestamp,omitempty"`
+ TraceID string `json:"trace_id,omitempty"`
+ SpanID string `json:"span_id,omitempty"`
+ ParentID string `json:"parent_id,omitempty"`
+ ServiceName string `json:"service_name,omitempty"`
+ OperationName string `json:"operation_name,omitempty"`
+ Status string `json:"status,omitempty"`
+ DurationMS float64 `json:"duration_ms,omitempty"`
+ Attributes map[string]any `json:"attributes,omitempty"`
+ Cells map[string]any `json:"cells,omitempty"`
+ Raw map[string]any `json:"raw,omitempty"`
+ Children []Trace `json:"children,omitempty"`
+}
+
+func parseSearchResult(result map[string]any, profile TracingProfile) TraceResult {
+ hitsObj, _ := result["hits"].(map[string]any)
+ hits, _ := hitsObj["hits"].([]any)
+ traces := make([]Trace, 0, len(hits))
+ for _, hitRaw := range hits {
+ hit, _ := hitRaw.(map[string]any)
+ source, _ := hit["_source"].(map[string]any)
+ if source == nil {
+ source = map[string]any{}
+ }
+ fields, _ := hit["fields"].(map[string]any)
+ merged := cloneAnyMap(source)
+ for k, v := range fields {
+ if _, ok := merged[k]; !ok {
+ merged[k] = unwrapFieldValue(v)
+ }
+ }
+ trace := traceFromDocument(merged, profile)
+ trace.Raw = merged
+ trace.Cells = evalCells(trace, profile.Columns)
+ traces = append(traces, trace)
+ }
+ return TraceResult{
+ Profile: profile.Name,
+ Index: profile.Index,
+ Total: totalHits(hitsObj, len(traces)),
+ Traces: buildTraceTree(traces),
+ }
+}
+
+func traceFromDocument(doc map[string]any, profile TracingProfile) Trace {
+ attrs := flattenDocument(doc)
+ trace := Trace{
+ Timestamp: stringValue(firstPath(doc, profile.DateField, "@timestamp", "timestamp", "startTimeMillis")),
+ TraceID: stringValue(firstPath(doc, profile.TraceIDField, "trace_id", "traceID")),
+ SpanID: stringValue(firstPath(doc, profile.SpanIDField, "span_id", "spanID")),
+ ParentID: parentID(doc, profile),
+ ServiceName: stringValue(firstPath(doc, profile.ServiceField, "service_name", "process.serviceName")),
+ OperationName: stringValue(firstPath(doc, profile.OperationField, "operation_name", "operationName")),
+ DurationMS: durationMillis(firstPath(doc, "duration_ms", "duration", "durationNano", "duration_nano")),
+ Attributes: attrs,
+ }
+ trace.Status = statusValue(doc, attrs, profile)
+ if ts := normalizeTimestamp(trace.Timestamp); ts != "" {
+ trace.Timestamp = ts
+ }
+ return trace
+}
+
+func evalCells(trace Trace, columns []TracingColumn) map[string]any {
+ env := map[string]any{
+ "timestamp": trace.Timestamp,
+ "trace_id": trace.TraceID,
+ "span_id": trace.SpanID,
+ "parent_id": trace.ParentID,
+ "service_name": trace.ServiceName,
+ "operation_name": trace.OperationName,
+ "status": trace.Status,
+ "duration_ms": trace.DurationMS,
+ }
+ for k, v := range trace.Attributes {
+ env[k] = v
+ }
+ out := make(map[string]any, len(columns))
+ for _, col := range columns {
+ if col.Name == "" || col.Field == "" {
+ continue
+ }
+ if v, ok := env[col.Field]; ok {
+ out[col.Name] = v
+ continue
+ }
+ if v := lookupPath(trace.Raw, col.Field); v != nil {
+ out[col.Name] = v
+ }
+ }
+ return out
+}
+
+func parentID(doc map[string]any, profile TracingProfile) string {
+ if profile.Format == "jaeger" {
+ if refs, ok := doc["references"].([]any); ok {
+ for _, raw := range refs {
+ ref, _ := raw.(map[string]any)
+ if profile.ParentRefType != "" {
+ if stringValue(ref["refType"]) != profile.ParentRefType {
+ continue
+ }
+ }
+ if id := stringValue(firstPath(ref, "spanID", "span_id")); id != "" {
+ return id
+ }
+ }
+ }
+ }
+ return stringValue(firstPath(doc, profile.ParentIDField, "parent_id", "parentID"))
+}
+
+func statusValue(doc map[string]any, attrs map[string]any, profile TracingProfile) string {
+ for _, field := range profile.StatusFields {
+ if v := stringValue(lookupPath(doc, field)); v != "" {
+ return v
+ }
+ if v := stringValue(attrs[field]); v != "" {
+ return v
+ }
+ }
+ for _, field := range []string{"status", "status.code", "tag.error", "error"} {
+ if v := stringValue(lookupPath(doc, field)); v != "" {
+ return v
+ }
+ if v := stringValue(attrs[field]); v != "" {
+ return v
+ }
+ }
+ return ""
+}
+
+func buildTraceTree(flat []Trace) []Trace {
+ byID := map[string]*Trace{}
+ for i := range flat {
+ if flat[i].SpanID != "" {
+ byID[flat[i].SpanID] = &flat[i]
+ }
+ }
+ var roots []Trace
+ for i := range flat {
+ if flat[i].ParentID != "" {
+ if parent, ok := byID[flat[i].ParentID]; ok {
+ parent.Children = append(parent.Children, flat[i])
+ continue
+ }
+ }
+ roots = append(roots, flat[i])
+ }
+ if len(roots) == 0 {
+ return flat
+ }
+ return roots
+}
+
+func flattenDocument(doc map[string]any) map[string]any {
+ out := map[string]any{}
+ var walk func(string, any)
+ walk = func(prefix string, value any) {
+ switch v := value.(type) {
+ case map[string]any:
+ for key, child := range v {
+ next := key
+ if prefix != "" {
+ next = prefix + "." + key
+ }
+ walk(next, child)
+ }
+ case []any:
+ if isJaegerTags(prefix, v) {
+ for _, raw := range v {
+ tag, _ := raw.(map[string]any)
+ key := stringValue(tag["key"])
+ if key == "" {
+ continue
+ }
+ out["tag."+key] = firstPath(tag, "value", "vStr", "vDouble", "vBool", "vLong")
+ }
+ return
+ }
+ out[prefix] = v
+ default:
+ out[prefix] = v
+ }
+ }
+ walk("", doc)
+ return out
+}
+
+func isJaegerTags(prefix string, values []any) bool {
+ if prefix != "tags" && prefix != "process.tags" {
+ return false
+ }
+ if len(values) == 0 {
+ return false
+ }
+ first, ok := values[0].(map[string]any)
+ if !ok {
+ return false
+ }
+ _, hasKey := first["key"]
+ return hasKey
+}
+
+func firstPath(doc map[string]any, paths ...string) any {
+ for _, path := range paths {
+ if path == "" {
+ continue
+ }
+ if v := lookupPath(doc, path); v != nil {
+ return v
+ }
+ }
+ return nil
+}
+
+func lookupPath(doc map[string]any, dotted string) any {
+ if doc == nil || dotted == "" {
+ return nil
+ }
+ if v, ok := doc[dotted]; ok {
+ return v
+ }
+ parts := strings.Split(dotted, ".")
+ var cur any = doc
+ for _, part := range parts {
+ switch typed := cur.(type) {
+ case map[string]any:
+ cur = typed[part]
+ case []any:
+ if len(typed) == 0 {
+ return nil
+ }
+ cur = typed[0]
+ if m, ok := cur.(map[string]any); ok {
+ cur = m[part]
+ }
+ default:
+ return nil
+ }
+ if cur == nil {
+ return nil
+ }
+ }
+ return cur
+}
+
+func unwrapFieldValue(v any) any {
+ if arr, ok := v.([]any); ok && len(arr) == 1 {
+ return arr[0]
+ }
+ return v
+}
+
+func stringValue(v any) string {
+ switch t := unwrapFieldValue(v).(type) {
+ case nil:
+ return ""
+ case string:
+ return t
+ case json.Number:
+ return t.String()
+ case float64:
+ if math.Trunc(t) == t {
+ return strconv.FormatInt(int64(t), 10)
+ }
+ return strconv.FormatFloat(t, 'f', -1, 64)
+ case bool:
+ return strconv.FormatBool(t)
+ default:
+ return fmt.Sprint(t)
+ }
+}
+
+func durationMillis(v any) float64 {
+ switch t := unwrapFieldValue(v).(type) {
+ case float64:
+ if t > 1_000_000 {
+ return math.Round(t/10_000) / 100
+ }
+ return t
+ case int:
+ return float64(t)
+ case string:
+ n, _ := strconv.ParseFloat(t, 64)
+ if n > 1_000_000 {
+ return math.Round(n/10_000) / 100
+ }
+ return n
+ default:
+ return 0
+ }
+}
+
+func normalizeTimestamp(raw string) string {
+ if raw == "" {
+ return ""
+ }
+ if n, err := strconv.ParseInt(raw, 10, 64); err == nil {
+ if n > 10_000_000_000_000 {
+ return time.UnixMilli(n).Format(time.RFC3339Nano)
+ }
+ return time.Unix(n, 0).Format(time.RFC3339Nano)
+ }
+ if ts, err := time.Parse(time.RFC3339Nano, raw); err == nil {
+ return ts.Format(time.RFC3339Nano)
+ }
+ return raw
+}
+
+func totalHits(hits map[string]any, fallback int) int {
+ total, ok := hits["total"].(map[string]any)
+ if !ok {
+ return fallback
+ }
+ switch v := total["value"].(type) {
+ case float64:
+ return int(v)
+ case int:
+ return v
+ default:
+ return fallback
+ }
+}
+
+func cloneAnyMap(in map[string]any) map[string]any {
+ out := make(map[string]any, len(in))
+ for k, v := range in {
+ out[k] = v
+ }
+ return out
+}
diff --git a/opensearch/parser_test.go b/opensearch/parser_test.go
new file mode 100644
index 0000000..2cec94c
--- /dev/null
+++ b/opensearch/parser_test.go
@@ -0,0 +1,43 @@
+package main
+
+import "testing"
+
+func TestParseJaegerSearchResult(t *testing.T) {
+ profile, err := defaultSettings().resolveProfile("jaeger")
+ if err != nil {
+ t.Fatal(err)
+ }
+ result := map[string]any{
+ "hits": map[string]any{
+ "total": map[string]any{"value": float64(1)},
+ "hits": []any{
+ map[string]any{
+ "_source": map[string]any{
+ "traceID": "t1",
+ "spanID": "s1",
+ "operationName": "GET /health",
+ "startTimeMillis": float64(1710000000000),
+ "duration": float64(123000),
+ "process": map[string]any{
+ "serviceName": "api",
+ },
+ "tags": []any{
+ map[string]any{"key": "otel@status_code", "value": "OK"},
+ },
+ },
+ },
+ },
+ },
+ }
+ parsed := parseSearchResult(result, profile)
+ if parsed.Total != 1 || len(parsed.Traces) != 1 {
+ t.Fatalf("unexpected result: %#v", parsed)
+ }
+ trace := parsed.Traces[0]
+ if trace.TraceID != "t1" || trace.ServiceName != "api" || trace.OperationName != "GET /health" {
+ t.Fatalf("unexpected trace: %#v", trace)
+ }
+ if trace.Status != "OK" {
+ t.Fatalf("status = %q", trace.Status)
+ }
+}
diff --git a/opensearch/profile.go b/opensearch/profile.go
new file mode 100644
index 0000000..c076c12
--- /dev/null
+++ b/opensearch/profile.go
@@ -0,0 +1,383 @@
+package main
+
+import (
+ "embed"
+ "fmt"
+ "io/fs"
+ "path"
+ "sort"
+ "strings"
+
+ "gopkg.in/yaml.v3"
+)
+
+//go:embed profiles/*.yaml
+var profileFS embed.FS
+
+type TracingProfile struct {
+ Name string `yaml:"name,omitempty" json:"name,omitempty"`
+ Hidden bool `yaml:"hidden,omitempty" json:"hidden,omitempty"`
+ Format string `yaml:"format,omitempty" json:"format,omitempty"`
+ Index string `yaml:"index,omitempty" json:"index,omitempty"`
+ DateField string `yaml:"dateField,omitempty" json:"dateField,omitempty"`
+ TraceIDField string `yaml:"traceIdField,omitempty" json:"traceIdField,omitempty"`
+ SpanIDField string `yaml:"spanIdField,omitempty" json:"spanIdField,omitempty"`
+ ParentIDField string `yaml:"parentIdField,omitempty" json:"parentIdField,omitempty"`
+ ParentRefType string `yaml:"parentRefType,omitempty" json:"parentRefType,omitempty"`
+ ServiceField string `yaml:"serviceField,omitempty" json:"serviceField,omitempty"`
+ OperationField string `yaml:"operationField,omitempty" json:"operationField,omitempty"`
+ StatusFields []string `yaml:"statusFields,omitempty" json:"statusFields,omitempty"`
+ SelectFields []string `yaml:"selectFields,omitempty" json:"selectFields,omitempty"`
+ SourceExcludes []string `yaml:"sourceExcludes,omitempty" json:"sourceExcludes,omitempty"`
+ Imports []string `yaml:"imports,omitempty" json:"imports,omitempty"`
+ Defaults map[string]any `yaml:"defaults,omitempty" json:"defaults,omitempty"`
+ Params map[string]TracingParam `yaml:"params,omitempty" json:"params,omitempty"`
+ Columns []TracingColumn `yaml:"columns,omitempty" json:"columns,omitempty"`
+}
+
+type TracingParam struct {
+ Field string `yaml:"field,omitempty" json:"field,omitempty"`
+ Operator string `yaml:"operator,omitempty" json:"operator,omitempty"`
+ Clause string `yaml:"clause,omitempty" json:"clause,omitempty"`
+ Format string `yaml:"format,omitempty" json:"format,omitempty"`
+ Template string `yaml:"template,omitempty" json:"template,omitempty"`
+ Description string `yaml:"description,omitempty" json:"description,omitempty"`
+ Required bool `yaml:"required,omitempty" json:"required,omitempty"`
+ Internal bool `yaml:"internal,omitempty" json:"internal,omitempty"`
+}
+
+type TracingColumn struct {
+ Name string `yaml:"name,omitempty" json:"name,omitempty"`
+ Field string `yaml:"field,omitempty" json:"field,omitempty"`
+ Detail bool `yaml:"detail,omitempty" json:"detail,omitempty"`
+}
+
+type ProfileSummary struct {
+ Name string `json:"name"`
+ Format string `json:"format"`
+ Backend string `json:"backend"`
+ Index string `json:"index"`
+ Params []ProfileParam `json:"params"`
+ Columns []TracingColumn `json:"columns"`
+ Defaults map[string]any `json:"defaults"`
+ Profile *TracingProfile `json:"-"`
+}
+
+type ProfileParam struct {
+ Name string `json:"name"`
+ Operator string `json:"operator"`
+ Description string `json:"description"`
+ Required bool `json:"required"`
+}
+
+func defaultProfiles() map[string]TracingProfile {
+ entries, err := fs.ReadDir(profileFS, "profiles")
+ if err != nil {
+ panic(err)
+ }
+ out := make(map[string]TracingProfile, len(entries))
+ for _, entry := range entries {
+ if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".yaml") {
+ continue
+ }
+ data, err := profileFS.ReadFile(path.Join("profiles", entry.Name()))
+ if err != nil {
+ panic(err)
+ }
+ var p TracingProfile
+ if err := yaml.Unmarshal(data, &p); err != nil {
+ panic(err)
+ }
+ if p.Name == "" {
+ p.Name = strings.TrimSuffix(entry.Name(), ".yaml")
+ }
+ out[p.Name] = p
+ }
+ return out
+}
+
+func parseProfilesYAML(data []byte) (map[string]TracingProfile, error) {
+ var profiles map[string]TracingProfile
+ if err := yaml.Unmarshal(data, &profiles); err != nil {
+ var single TracingProfile
+ if err2 := yaml.Unmarshal(data, &single); err2 != nil {
+ return nil, fmt.Errorf("parse profilesYaml: %w", err)
+ }
+ if single.Name == "" {
+ return nil, fmt.Errorf("profilesYaml single profile requires name")
+ }
+ profiles = map[string]TracingProfile{single.Name: single}
+ }
+ for name, profile := range profiles {
+ if profile.Name == "" {
+ profile.Name = name
+ profiles[name] = profile
+ }
+ }
+ return profiles, nil
+}
+
+func (s PluginSettings) resolveProfile(name string) (TracingProfile, error) {
+ if strings.TrimSpace(name) == "" {
+ name = s.DefaultProfile
+ }
+ defaults := defaultProfiles()
+ custom := s.Profiles
+ resolved := map[string]TracingProfile{}
+ visiting := map[string]bool{}
+
+ var resolve func(string) (TracingProfile, error)
+ resolve = func(profileName string) (TracingProfile, error) {
+ if p, ok := resolved[profileName]; ok {
+ return p, nil
+ }
+ if visiting[profileName] {
+ return TracingProfile{}, fmt.Errorf("cyclic tracing profile import at %q", profileName)
+ }
+ visiting[profileName] = true
+ defer delete(visiting, profileName)
+
+ base, hasDefault := defaults[profileName]
+ override, hasCustom := custom[profileName]
+ if !hasDefault && !hasCustom {
+ return TracingProfile{}, fmt.Errorf("tracing profile %q not found", profileName)
+ }
+
+ profile := TracingProfile{Name: profileName}
+ for _, imported := range base.Imports {
+ p, err := resolve(imported)
+ if err != nil {
+ return TracingProfile{}, fmt.Errorf("resolve import %q for %q: %w", imported, profileName, err)
+ }
+ profile = mergeProfiles(profile, p)
+ }
+ profile = mergeProfiles(profile, base)
+ for _, imported := range override.Imports {
+ p, err := resolve(imported)
+ if err != nil {
+ return TracingProfile{}, fmt.Errorf("resolve import %q for %q: %w", imported, profileName, err)
+ }
+ profile = mergeProfiles(profile, p)
+ }
+ profile = mergeProfiles(profile, override)
+ if profile.Name == "" {
+ profile.Name = profileName
+ }
+ if s.Index != "" {
+ profile.Index = s.Index
+ }
+ profile = profile.withDefaults()
+ if err := profile.validate(); err != nil {
+ return TracingProfile{}, err
+ }
+ resolved[profileName] = profile
+ return profile, nil
+ }
+ return resolve(name)
+}
+
+func (s PluginSettings) profileNames() []string {
+ names := map[string]struct{}{}
+ for name := range defaultProfiles() {
+ names[name] = struct{}{}
+ }
+ for name := range s.Profiles {
+ names[name] = struct{}{}
+ }
+ out := make([]string, 0, len(names))
+ for name := range names {
+ p, err := s.resolveProfile(name)
+ if err == nil && !p.Hidden {
+ out = append(out, name)
+ }
+ }
+ sort.Slice(out, func(i, j int) bool {
+ leftDepth := strings.Count(out[i], ".")
+ rightDepth := strings.Count(out[j], ".")
+ if leftDepth != rightDepth {
+ return leftDepth < rightDepth
+ }
+ return out[i] < out[j]
+ })
+ return out
+}
+
+func (s PluginSettings) profileSummaries() ([]ProfileSummary, error) {
+ names := s.profileNames()
+ out := make([]ProfileSummary, 0, len(names))
+ for _, name := range names {
+ profile, err := s.resolveProfile(name)
+ if err != nil {
+ return nil, err
+ }
+ params := make([]ProfileParam, 0, len(profile.Params))
+ paramNames := make([]string, 0, len(profile.Params))
+ for name, param := range profile.Params {
+ if !param.Internal {
+ paramNames = append(paramNames, name)
+ }
+ }
+ sort.Strings(paramNames)
+ for _, name := range paramNames {
+ param := profile.Params[name]
+ params = append(params, ProfileParam{
+ Name: name,
+ Operator: firstNonEmpty(param.Operator, "term"),
+ Description: param.Description,
+ Required: param.Required,
+ })
+ }
+ p := profile
+ out = append(out, ProfileSummary{
+ Name: profile.Name,
+ Format: profile.Format,
+ Backend: "opensearch",
+ Index: profile.Index,
+ Params: params,
+ Columns: profile.Columns,
+ Defaults: cloneMap(profile.Defaults),
+ Profile: &p,
+ })
+ }
+ return out, nil
+}
+
+func (p TracingProfile) withDefaults() TracingProfile {
+ if p.Format == "" {
+ p.Format = "flat"
+ }
+ if p.Index == "" {
+ p.Index = "otel-traces-*"
+ }
+ if p.DateField == "" {
+ p.DateField = "@timestamp"
+ }
+ if p.TraceIDField == "" {
+ p.TraceIDField = "trace_id"
+ }
+ if p.SpanIDField == "" {
+ p.SpanIDField = "span_id"
+ }
+ if p.ParentIDField == "" {
+ p.ParentIDField = "parent_id"
+ }
+ if p.ServiceField == "" {
+ p.ServiceField = "service_name"
+ }
+ if p.OperationField == "" {
+ p.OperationField = "operation_name"
+ }
+ if p.Params == nil {
+ p.Params = map[string]TracingParam{}
+ }
+ if p.Defaults == nil {
+ p.Defaults = map[string]any{}
+ }
+ if len(p.Columns) == 0 {
+ p.Columns = []TracingColumn{
+ {Name: "Time", Field: "timestamp"},
+ {Name: "Service", Field: "service_name"},
+ {Name: "Operation", Field: "operation_name"},
+ {Name: "Status", Field: "status"},
+ {Name: "Trace ID", Field: "trace_id"},
+ }
+ }
+ return p
+}
+
+func (p TracingProfile) validate() error {
+ if p.Name == "" {
+ return fmt.Errorf("tracing profile name is required")
+ }
+ if p.Index == "" {
+ return fmt.Errorf("tracing profile %q index is required", p.Name)
+ }
+ if p.DateField == "" {
+ return fmt.Errorf("tracing profile %q dateField is required", p.Name)
+ }
+ for name, param := range p.Params {
+ if param.Field == "" {
+ return fmt.Errorf("tracing profile %q param %q field is required", p.Name, name)
+ }
+ }
+ return nil
+}
+
+func mergeProfiles(base, override TracingProfile) TracingProfile {
+ out := base
+ if override.Name != "" {
+ out.Name = override.Name
+ }
+ if override.Hidden {
+ out.Hidden = true
+ }
+ if override.Format != "" {
+ out.Format = override.Format
+ }
+ if override.Index != "" {
+ out.Index = override.Index
+ }
+ if override.DateField != "" {
+ out.DateField = override.DateField
+ }
+ if override.TraceIDField != "" {
+ out.TraceIDField = override.TraceIDField
+ }
+ if override.SpanIDField != "" {
+ out.SpanIDField = override.SpanIDField
+ }
+ if override.ParentIDField != "" {
+ out.ParentIDField = override.ParentIDField
+ }
+ if override.ParentRefType != "" {
+ out.ParentRefType = override.ParentRefType
+ }
+ if override.ServiceField != "" {
+ out.ServiceField = override.ServiceField
+ }
+ if override.OperationField != "" {
+ out.OperationField = override.OperationField
+ }
+ if len(override.StatusFields) > 0 {
+ out.StatusFields = append([]string(nil), override.StatusFields...)
+ }
+ if len(override.SelectFields) > 0 {
+ out.SelectFields = append([]string(nil), override.SelectFields...)
+ }
+ if len(override.SourceExcludes) > 0 {
+ out.SourceExcludes = append([]string(nil), override.SourceExcludes...)
+ }
+ if len(override.Columns) > 0 {
+ out.Columns = append([]TracingColumn(nil), override.Columns...)
+ }
+ if out.Defaults == nil {
+ out.Defaults = map[string]any{}
+ }
+ for k, v := range override.Defaults {
+ out.Defaults[k] = v
+ }
+ if out.Params == nil {
+ out.Params = map[string]TracingParam{}
+ }
+ for k, v := range override.Params {
+ out.Params[k] = v
+ }
+ return out
+}
+
+func firstNonEmpty(values ...string) string {
+ for _, v := range values {
+ if v != "" {
+ return v
+ }
+ }
+ return ""
+}
+
+func cloneMap(in map[string]any) map[string]any {
+ out := make(map[string]any, len(in))
+ for k, v := range in {
+ out[k] = v
+ }
+ return out
+}
diff --git a/opensearch/profile_test.go b/opensearch/profile_test.go
new file mode 100644
index 0000000..b0db192
--- /dev/null
+++ b/opensearch/profile_test.go
@@ -0,0 +1,47 @@
+package main
+
+import "testing"
+
+func TestResolveProfileIncludesDefaults(t *testing.T) {
+ profile, err := defaultSettings().resolveProfile("jaeger")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if profile.Index != "jaeger-span*" {
+ t.Fatalf("index = %q", profile.Index)
+ }
+ if _, ok := profile.Params["trace_id"]; !ok {
+ t.Fatalf("trace_id param missing")
+ }
+}
+
+func TestBuildTraceQueryRejectsUnknownFilter(t *testing.T) {
+ profile, err := defaultSettings().resolveProfile("otel")
+ if err != nil {
+ t.Fatal(err)
+ }
+ _, err = buildTraceQuery(QueryBuildOptions{Params: map[string]any{"missing": "x"}}, profile)
+ if err == nil {
+ t.Fatalf("expected unsupported filter error")
+ }
+}
+
+func TestBuildTraceQueryUsesTermsForCSV(t *testing.T) {
+ profile := TracingProfile{
+ Name: "test",
+ Index: "traces-*",
+ DateField: "@timestamp",
+ Params: map[string]TracingParam{
+ "trace_id": {Field: "trace_id", Operator: "term"},
+ },
+ }.withDefaults()
+ query, err := buildTraceQuery(QueryBuildOptions{Params: map[string]any{"trace_id": "a,b"}}, profile)
+ if err != nil {
+ t.Fatal(err)
+ }
+ boolQuery := query["query"].(map[string]any)["bool"].(map[string]any)
+ filter := boolQuery["filter"].([]map[string]any)
+ if _, ok := filter[0]["terms"]; !ok {
+ t.Fatalf("expected terms query, got %#v", filter[0])
+ }
+}
diff --git a/opensearch/profiles/jaeger.yaml b/opensearch/profiles/jaeger.yaml
new file mode 100644
index 0000000..ba52e28
--- /dev/null
+++ b/opensearch/profiles/jaeger.yaml
@@ -0,0 +1,56 @@
+name: jaeger
+format: jaeger
+index: jaeger-span*
+dateField: startTimeMillis
+traceIdField: traceID
+spanIdField: spanID
+parentIdField: references.spanID
+parentRefType: CHILD_OF
+serviceField: process.serviceName
+operationField: operationName
+statusFields:
+ - tag.otel@status_code
+ - tag.error
+ - tag.error.message
+ - tag.exception.message
+selectFields:
+ - traceID
+ - spanID
+ - operationName
+ - duration
+params:
+ trace_id:
+ field: traceID
+ operator: term
+ description: Trace ID
+ span_id:
+ field: spanID
+ operator: term
+ description: Span ID
+ service:
+ field: process.serviceName
+ operator: term
+ description: Service name
+ operation:
+ field: operationName
+ operator: match_phrase
+ description: Operation name
+ status:
+ field: tag.otel@status_code
+ operator: term
+ description: Status code
+columns:
+ - name: Time
+ field: timestamp
+ - name: Service
+ field: service_name
+ - name: Operation
+ field: operation_name
+ - name: Status
+ field: status
+ - name: Duration
+ field: duration_ms
+ - name: Trace ID
+ field: trace_id
+ - name: Span ID
+ field: span_id
diff --git a/opensearch/profiles/otel.yaml b/opensearch/profiles/otel.yaml
new file mode 100644
index 0000000..0832375
--- /dev/null
+++ b/opensearch/profiles/otel.yaml
@@ -0,0 +1,55 @@
+name: otel
+format: flat
+index: otel-traces-*
+dateField: "@timestamp"
+traceIdField: trace_id
+spanIdField: span_id
+parentIdField: parent_id
+serviceField: service_name
+operationField: operation_name
+statusFields:
+ - status
+ - status.code
+ - attributes.error
+selectFields:
+ - trace_id
+ - span_id
+ - parent_id
+ - service_name
+ - operation_name
+params:
+ trace_id:
+ field: trace_id
+ operator: term
+ description: Trace ID
+ span_id:
+ field: span_id
+ operator: term
+ description: Span ID
+ service:
+ field: service_name
+ operator: term
+ description: Service name
+ operation:
+ field: operation_name
+ operator: match_phrase
+ description: Operation name
+ status:
+ field: status
+ operator: term
+ description: Status
+columns:
+ - name: Time
+ field: timestamp
+ - name: Service
+ field: service_name
+ - name: Operation
+ field: operation_name
+ - name: Status
+ field: status
+ - name: Duration
+ field: duration_ms
+ - name: Trace ID
+ field: trace_id
+ - name: Span ID
+ field: span_id
diff --git a/opensearch/query.go b/opensearch/query.go
new file mode 100644
index 0000000..1c4bb09
--- /dev/null
+++ b/opensearch/query.go
@@ -0,0 +1,253 @@
+package main
+
+import (
+ "fmt"
+ "sort"
+ "strings"
+)
+
+const (
+ clauseFilter = "filter"
+ clauseMust = "must"
+ clauseShould = "should"
+ clauseMustNot = "must_not"
+)
+
+type QueryBuildOptions struct {
+ From string
+ To string
+ Params map[string]any
+}
+
+type TraceQueryPreview struct {
+ Profile string `json:"profile"`
+ Request TraceQueryPreviewRequest `json:"request"`
+}
+
+type TraceQueryPreviewRequest struct {
+ Index string `json:"index"`
+ Limit int `json:"limit"`
+ Query map[string]any `json:"query"`
+}
+
+func buildQueryPreview(profile TracingProfile, req TraceQueryRequest) (TraceQueryPreview, error) {
+ limit := req.Limit
+ if limit <= 0 {
+ limit = 100
+ }
+ query, err := buildTraceQuery(QueryBuildOptions{From: req.From, To: req.To, Params: req.Params}, profile)
+ if err != nil {
+ return TraceQueryPreview{}, err
+ }
+ return TraceQueryPreview{
+ Profile: profile.Name,
+ Request: TraceQueryPreviewRequest{
+ Index: profile.Index,
+ Limit: limit,
+ Query: query,
+ },
+ }, nil
+}
+
+func buildTraceQuery(opts QueryBuildOptions, profile TracingProfile) (map[string]any, error) {
+ queryParams, err := mergeQueryParams(profile, opts.Params)
+ if err != nil {
+ return nil, err
+ }
+
+ boolClauses := map[string][]map[string]any{
+ clauseFilter: {},
+ clauseMust: {},
+ clauseShould: {},
+ clauseMustNot: {},
+ }
+
+ names := make([]string, 0, len(queryParams))
+ for name := range queryParams {
+ names = append(names, name)
+ }
+ sort.Strings(names)
+ for _, name := range names {
+ param, ok := profile.Params[name]
+ if !ok {
+ return nil, fmt.Errorf("filter %q is not supported by tracing profile %q", name, profile.Name)
+ }
+ clauses, err := buildParamClauses(param, queryParams[name])
+ if err != nil {
+ return nil, fmt.Errorf("build filter %q: %w", name, err)
+ }
+ bucket := firstNonEmpty(param.Clause, clauseFilter)
+ if _, ok := boolClauses[bucket]; !ok {
+ return nil, fmt.Errorf("unsupported clause %q for filter %q", bucket, name)
+ }
+ boolClauses[bucket] = append(boolClauses[bucket], clauses...)
+ }
+
+ rangeQuery := map[string]any{}
+ if strings.TrimSpace(opts.From) != "" {
+ rangeQuery["gte"] = strings.TrimSpace(opts.From)
+ }
+ if strings.TrimSpace(opts.To) != "" {
+ rangeQuery["lte"] = strings.TrimSpace(opts.To)
+ }
+ if len(rangeQuery) > 0 {
+ rangeQuery["format"] = "strict_date_optional_time||epoch_millis"
+ boolClauses[clauseFilter] = append(boolClauses[clauseFilter], map[string]any{
+ "range": map[string]any{profile.DateField: rangeQuery},
+ })
+ }
+
+ query := map[string]any{
+ "sort": []map[string]any{{profile.DateField: map[string]any{"order": "desc"}}},
+ }
+ if len(profile.SelectFields) > 0 {
+ query["stored_fields"] = []string{"*"}
+ query["fields"] = profile.SelectFields
+ }
+ if profile.DateField != "" {
+ query["docvalue_fields"] = []map[string]any{{"field": profile.DateField, "format": "date_time"}}
+ }
+ if len(profile.SourceExcludes) > 0 {
+ query["_source"] = map[string]any{"excludes": profile.SourceExcludes}
+ }
+
+ boolQuery := map[string]any{}
+ for _, bucket := range []string{clauseFilter, clauseMust, clauseShould, clauseMustNot} {
+ if len(boolClauses[bucket]) > 0 {
+ boolQuery[bucket] = boolClauses[bucket]
+ }
+ }
+ if len(boolQuery) > 0 {
+ if len(boolClauses[clauseShould]) > 0 {
+ boolQuery["minimum_should_match"] = 1
+ }
+ query["query"] = map[string]any{"bool": boolQuery}
+ } else {
+ query["query"] = map[string]any{"match_all": map[string]any{}}
+ }
+ return query, nil
+}
+
+func mergeQueryParams(profile TracingProfile, overrides map[string]any) (map[string]any, error) {
+ params := cloneMap(profile.Defaults)
+ for key, value := range overrides {
+ if isEmptyParamValue(value) {
+ continue
+ }
+ if param, ok := profile.Params[key]; ok && param.Internal {
+ return nil, fmt.Errorf("filter %q is internal to tracing profile %q", key, profile.Name)
+ }
+ params[key] = value
+ }
+ var missing []string
+ for name, param := range profile.Params {
+ if !param.Required {
+ continue
+ }
+ if isEmptyParamValue(params[name]) {
+ missing = append(missing, name)
+ }
+ }
+ if len(missing) > 0 {
+ sort.Strings(missing)
+ return nil, fmt.Errorf("tracing profile %q requires param(s): %s", profile.Name, strings.Join(missing, ", "))
+ }
+ return params, nil
+}
+
+func buildParamClauses(param TracingParam, value any) ([]map[string]any, error) {
+ values := normalizeParamValues(value)
+ if len(values) == 0 {
+ return nil, nil
+ }
+ formatted := make([]any, 0, len(values))
+ for _, item := range values {
+ formatted = append(formatted, formatParamValue(param, item))
+ }
+ switch firstNonEmpty(param.Operator, "term") {
+ case "term":
+ if len(formatted) > 1 {
+ return []map[string]any{{"terms": map[string]any{param.Field: formatted}}}, nil
+ }
+ return []map[string]any{{"term": map[string]any{param.Field: formatted[0]}}}, nil
+ case "terms":
+ return []map[string]any{{"terms": map[string]any{param.Field: formatted}}}, nil
+ case "match_phrase":
+ out := make([]map[string]any, 0, len(formatted))
+ for _, item := range formatted {
+ out = append(out, map[string]any{"match_phrase": map[string]any{param.Field: item}})
+ }
+ return out, nil
+ case "wildcard":
+ out := make([]map[string]any, 0, len(formatted))
+ for _, item := range formatted {
+ out = append(out, map[string]any{"wildcard": map[string]any{param.Field: item}})
+ }
+ return out, nil
+ case "query_string":
+ out := make([]map[string]any, 0, len(formatted))
+ for _, item := range formatted {
+ out = append(out, map[string]any{"query_string": map[string]any{"fields": []string{param.Field}, "query": item}})
+ }
+ return out, nil
+ case "exists":
+ return []map[string]any{{"exists": map[string]any{"field": param.Field}}}, nil
+ default:
+ return nil, fmt.Errorf("unsupported operator %q", param.Operator)
+ }
+}
+
+func formatParamValue(param TracingParam, value any) any {
+ s, ok := value.(string)
+ if !ok {
+ return value
+ }
+ if param.Template != "" {
+ return strings.ReplaceAll(param.Template, "{value}", s)
+ }
+ return s
+}
+
+func normalizeParamValues(value any) []any {
+ switch v := value.(type) {
+ case nil:
+ return nil
+ case []any:
+ return v
+ case []string:
+ out := make([]any, 0, len(v))
+ for _, item := range v {
+ out = append(out, item)
+ }
+ return out
+ case string:
+ if strings.Contains(v, ",") {
+ parts := strings.Split(v, ",")
+ out := make([]any, 0, len(parts))
+ for _, part := range parts {
+ if trimmed := strings.TrimSpace(part); trimmed != "" {
+ out = append(out, trimmed)
+ }
+ }
+ return out
+ }
+ return []any{v}
+ default:
+ return []any{v}
+ }
+}
+
+func isEmptyParamValue(value any) bool {
+ switch v := value.(type) {
+ case nil:
+ return true
+ case string:
+ return strings.TrimSpace(v) == ""
+ case []any:
+ return len(v) == 0
+ case []string:
+ return len(v) == 0
+ default:
+ return false
+ }
+}
diff --git a/opensearch/ui-src/index.html b/opensearch/ui-src/index.html
new file mode 100644
index 0000000..edd32ec
--- /dev/null
+++ b/opensearch/ui-src/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ OpenSearch
+
+
+
+
+
+
diff --git a/opensearch/ui-src/package.json b/opensearch/ui-src/package.json
new file mode 100644
index 0000000..81cdf90
--- /dev/null
+++ b/opensearch/ui-src/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "@flanksource/opensearch-plugin-ui",
+ "private": true,
+ "version": "0.1.0",
+ "type": "module",
+ "scripts": {
+ "build": "tsc && vite build"
+ },
+ "dependencies": {
+ "@flanksource/clicky-ui": "^0.2.1",
+ "@tanstack/react-query": "^5.90.11",
+ "@vitejs/plugin-react": "^5.1.0",
+ "lucide-react": "^0.553.0",
+ "vite": "^7.2.4",
+ "typescript": "^5.9.3",
+ "react": "^19.2.0",
+ "react-dom": "^19.2.0"
+ },
+ "devDependencies": {
+ "@tailwindcss/vite": "^4.2.2",
+ "@types/react": "^19.2.7",
+ "@types/react-dom": "^19.2.3",
+ "tailwindcss": "^4.2.2"
+ }
+}
diff --git a/opensearch/ui-src/pnpm-lock.yaml b/opensearch/ui-src/pnpm-lock.yaml
new file mode 100644
index 0000000..45f4a97
--- /dev/null
+++ b/opensearch/ui-src/pnpm-lock.yaml
@@ -0,0 +1,4465 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ '@flanksource/clicky-ui':
+ specifier: ^0.2.1
+ version: 0.2.1(@tanstack/react-query@5.100.9(react@19.2.6))(@types/react@19.2.14)(@vue/compiler-sfc@3.5.33)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(tailwindcss@4.2.4)(typescript@5.9.3)
+ '@tanstack/react-query':
+ specifier: ^5.90.11
+ version: 5.100.9(react@19.2.6)
+ '@vitejs/plugin-react':
+ specifier: ^5.1.0
+ version: 5.2.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.7.0)(lightningcss@1.32.0)(yaml@2.8.4))
+ lucide-react:
+ specifier: ^0.553.0
+ version: 0.553.0(react@19.2.6)
+ react:
+ specifier: ^19.2.0
+ version: 19.2.6
+ react-dom:
+ specifier: ^19.2.0
+ version: 19.2.6(react@19.2.6)
+ typescript:
+ specifier: ^5.9.3
+ version: 5.9.3
+ vite:
+ specifier: ^7.2.4
+ version: 7.3.3(@types/node@24.12.3)(jiti@2.7.0)(lightningcss@1.32.0)(yaml@2.8.4)
+ devDependencies:
+ '@tailwindcss/vite':
+ specifier: ^4.2.2
+ version: 4.2.4(vite@7.3.3(@types/node@24.12.3)(jiti@2.7.0)(lightningcss@1.32.0)(yaml@2.8.4))
+ '@types/react':
+ specifier: ^19.2.7
+ version: 19.2.14
+ '@types/react-dom':
+ specifier: ^19.2.3
+ version: 19.2.3(@types/react@19.2.14)
+ tailwindcss:
+ specifier: ^4.2.2
+ version: 4.2.4
+
+packages:
+
+ '@ai-sdk/gateway@3.0.13':
+ resolution: {integrity: sha512-g7nE4PFtngOZNZSy1lOPpkC+FAiHxqBJXqyRMEG7NUrEVZlz5goBdtHg1YgWRJIX776JTXAmbOI5JreAKVAsVA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ zod: ^3.25.76 || ^4.1.8
+
+ '@ai-sdk/provider-utils@4.0.5':
+ resolution: {integrity: sha512-Ow/X/SEkeExTTc1x+nYLB9ZHK2WUId8+9TlkamAx7Tl9vxU+cKzWx2dwjgMHeCN6twrgwkLrrtqckQeO4mxgVA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ zod: ^3.25.76 || ^4.1.8
+
+ '@ai-sdk/provider@3.0.2':
+ resolution: {integrity: sha512-HrEmNt/BH/hkQ7zpi2o6N3k1ZR1QTb7z85WYhYygiTxOQuaml4CMtHCWRbric5WPU+RNsYI7r1EpyVQMKO1pYw==}
+ engines: {node: '>=18'}
+
+ '@ai-sdk/vue@3.0.33':
+ resolution: {integrity: sha512-czM9Js3a7f+Eo35gjEYEeJYUoPvMg5Dfi4bOLyDBghLqn0gaVg8yTmTaSuHCg+3K/+1xPjyXd4+2XcQIohWWiQ==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ vue: ^3.3.4
+
+ '@babel/code-frame@7.29.0':
+ resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/compat-data@7.29.3':
+ resolution: {integrity: sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/core@7.29.0':
+ resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/generator@7.29.1':
+ resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-compilation-targets@7.28.6':
+ resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-globals@7.28.0':
+ resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-imports@7.28.6':
+ resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-transforms@7.28.6':
+ resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+
+ '@babel/helper-plugin-utils@7.28.6':
+ resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-string-parser@7.27.1':
+ resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.28.5':
+ resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-option@7.27.1':
+ resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helpers@7.29.2':
+ resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.29.3':
+ resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/plugin-transform-react-jsx-self@7.27.1':
+ resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-transform-react-jsx-source@7.27.1':
+ resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/template@7.28.6':
+ resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/traverse@7.29.0':
+ resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/types@7.29.0':
+ resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
+ engines: {node: '>=6.9.0'}
+
+ '@codemirror/autocomplete@6.20.1':
+ resolution: {integrity: sha512-1cvg3Vz1dSSToCNlJfRA2WSI4ht3K+WplO0UMOgmUYPivCyy2oueZY6Lx7M9wThm7SDUBViRmuT+OG/i8+ON9A==}
+
+ '@codemirror/commands@6.10.3':
+ resolution: {integrity: sha512-JFRiqhKu+bvSkDLI+rUhJwSxQxYb759W5GBezE8Uc8mHLqC9aV/9aTC7yJSqCtB3F00pylrLCwnyS91Ap5ej4Q==}
+
+ '@codemirror/lang-css@6.3.1':
+ resolution: {integrity: sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==}
+
+ '@codemirror/lang-html@6.4.11':
+ resolution: {integrity: sha512-9NsXp7Nwp891pQchI7gPdTwBuSuT3K65NGTHWHNJ55HjYcHLllr0rbIZNdOzas9ztc1EUVBlHou85FFZS4BNnw==}
+
+ '@codemirror/lang-javascript@6.2.5':
+ resolution: {integrity: sha512-zD4e5mS+50htS7F+TYjBPsiIFGanfVqg4HyUz6WNFikgOPf2BgKlx+TQedI1w6n/IqRBVBbBWmGFdLB/7uxO4A==}
+
+ '@codemirror/lang-json@6.0.2':
+ resolution: {integrity: sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==}
+
+ '@codemirror/lang-xml@6.1.0':
+ resolution: {integrity: sha512-3z0blhicHLfwi2UgkZYRPioSgVTo9PV5GP5ducFH6FaHy0IAJRg+ixj5gTR1gnT/glAIC8xv4w2VL1LoZfs+Jg==}
+
+ '@codemirror/lang-yaml@6.1.3':
+ resolution: {integrity: sha512-AZ8DJBuXGVHybpBQhmZtgew5//4hv3tdkXnr3vDmOUMJRuB6vn/uuwtmTOTlqEaQFg3hQSVeA90NmvIQyUV6FQ==}
+
+ '@codemirror/language@6.12.3':
+ resolution: {integrity: sha512-QwCZW6Tt1siP37Jet9Tb02Zs81TQt6qQrZR2H+eGMcFsL1zMrk2/b9CLC7/9ieP1fjIUMgviLWMmgiHoJrj+ZA==}
+
+ '@codemirror/lint@6.9.5':
+ resolution: {integrity: sha512-GElsbU9G7QT9xXhpUg1zWGmftA/7jamh+7+ydKRuT0ORpWS3wOSP0yT1FOlIZa7mIJjpVPipErsyvVqB9cfTFA==}
+
+ '@codemirror/state@6.6.0':
+ resolution: {integrity: sha512-4nbvra5R5EtiCzr9BTHiTLc+MLXK2QGiAVYMyi8PkQd3SR+6ixar/Q/01Fa21TBIDOZXgeWV4WppsQolSreAPQ==}
+
+ '@codemirror/view@6.41.1':
+ resolution: {integrity: sha512-ToDnWKbBnke+ZLrP6vgTTDScGi5H37YYuZGniQaBzxMVdtCxMrslsmtnOvbPZk4RX9bvkQqnWR/WS/35tJA0qg==}
+
+ '@esbuild/aix-ppc64@0.27.7':
+ resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.27.7':
+ resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.27.7':
+ resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.27.7':
+ resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.27.7':
+ resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.27.7':
+ resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.27.7':
+ resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.27.7':
+ resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.27.7':
+ resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.27.7':
+ resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.27.7':
+ resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.27.7':
+ resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.27.7':
+ resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.27.7':
+ resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.27.7':
+ resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.27.7':
+ resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.27.7':
+ resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.27.7':
+ resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.27.7':
+ resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.27.7':
+ resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.27.7':
+ resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.27.7':
+ resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.27.7':
+ resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.27.7':
+ resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.27.7':
+ resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.27.7':
+ resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@flanksource/clicky-ui@0.2.1':
+ resolution: {integrity: sha512-FEAv1a6UzG2A2+MvO3qYOQvyE75znPFDIncRIMgA7QUDs08pAJRzYXZcIhFI7euDV6KTTZ9tBuTO5TEe4svWSA==}
+ peerDependencies:
+ '@shikijs/transformers': ^1.24.0
+ '@tanstack/react-query': ^5.0.0
+ marked: ^15.0.0
+ react: ^18.0.0 || ^19.0.0
+ react-dom: ^18.0.0 || ^19.0.0
+ shiki: ^1.24.0
+ tailwindcss: ^3.4.0
+ peerDependenciesMeta:
+ '@shikijs/transformers':
+ optional: true
+ '@tanstack/react-query':
+ optional: true
+ marked:
+ optional: true
+ shiki:
+ optional: true
+
+ '@floating-ui/core@1.7.5':
+ resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==}
+
+ '@floating-ui/dom@1.7.6':
+ resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==}
+
+ '@floating-ui/utils@0.2.10':
+ resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
+
+ '@floating-ui/utils@0.2.11':
+ resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==}
+
+ '@floating-ui/vue@1.1.11':
+ resolution: {integrity: sha512-HzHKCNVxnGS35r9fCHBc3+uCnjw9IWIlCPL683cGgM9Kgj2BiAl8x1mS7vtvP6F9S/e/q4O6MApwSHj8hNLGfw==}
+
+ '@floating-ui/vue@1.1.9':
+ resolution: {integrity: sha512-BfNqNW6KA83Nexspgb9DZuz578R7HT8MZw1CfK9I6Ah4QReNWEJsXWHN+SdmOVLNGmTPDi+fDT535Df5PzMLbQ==}
+
+ '@headlessui/tailwindcss@0.2.2':
+ resolution: {integrity: sha512-xNe42KjdyA4kfUKLLPGzME9zkH7Q3rOZ5huFihWNWOQFxnItxPB3/67yBI8/qBfY8nwBRx5GHn4VprsoluVMGw==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ tailwindcss: ^3.0 || ^4.0
+
+ '@headlessui/vue@1.7.23':
+ resolution: {integrity: sha512-JzdCNqurrtuu0YW6QaDtR2PIYCKPUWq28csDyMvN4zmGccmE7lz40Is6hc3LA4HFeCI7sekZ/PQMTNmn9I/4Wg==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ vue: ^3.2.0
+
+ '@iconify/react@5.2.1':
+ resolution: {integrity: sha512-37GDR3fYDZmnmUn9RagyaX+zca24jfVOMY8E1IXTqJuE8pxNtN51KWPQe3VODOWvuUurq7q9uUu3CFrpqj5Iqg==}
+ peerDependencies:
+ react: '>=16'
+
+ '@iconify/types@2.0.0':
+ resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
+
+ '@internationalized/date@3.12.1':
+ resolution: {integrity: sha512-6IedsVWXyq4P9Tj+TxuU8WGWM70hYLl12nbYU8jkikVpa6WXapFazPUcHUMDMoWftIDE2ILDkFFte6W2nFCkRQ==}
+
+ '@internationalized/number@3.6.6':
+ resolution: {integrity: sha512-iFgmQaXHE0vytNfpLZWOC2mEJCBRzcUxt53Xf/yCXG93lRvqas237i3r7X4RKMwO3txiyZD4mQjKAByFv6UGSQ==}
+
+ '@jridgewell/gen-mapping@0.3.13':
+ resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
+
+ '@jridgewell/remapping@2.3.5':
+ resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+
+ '@lezer/common@1.5.2':
+ resolution: {integrity: sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==}
+
+ '@lezer/css@1.3.3':
+ resolution: {integrity: sha512-RzBo8r+/6QJeow7aPHIpGVIH59xTcJXp399820gZoMo9noQDRVpJLheIBUicYwKcsbOYoBRoLZlf2720dG/4Tg==}
+
+ '@lezer/highlight@1.2.3':
+ resolution: {integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==}
+
+ '@lezer/html@1.3.13':
+ resolution: {integrity: sha512-oI7n6NJml729m7pjm9lvLvmXbdoMoi2f+1pwSDJkl9d68zGr7a9Btz8NdHTGQZtW2DA25ybeuv/SyDb9D5tseg==}
+
+ '@lezer/javascript@1.5.4':
+ resolution: {integrity: sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==}
+
+ '@lezer/json@1.0.3':
+ resolution: {integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==}
+
+ '@lezer/lr@1.4.10':
+ resolution: {integrity: sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==}
+
+ '@lezer/xml@1.0.6':
+ resolution: {integrity: sha512-CdDwirL0OEaStFue/66ZmFSeppuL6Dwjlk8qk153mSQwiSH/Dlri4GNymrNWnUmPl2Um7QfV1FO9KFUyX3Twww==}
+
+ '@lezer/yaml@1.0.4':
+ resolution: {integrity: sha512-2lrrHqxalACEbxIbsjhqGpSW8kWpUKuY6RHgnSAFZa6qK62wvnPxA8hGOwOoDbwHcOFs5M4o27mjGu+P7TvBmw==}
+
+ '@marijn/find-cluster-break@1.0.2':
+ resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==}
+
+ '@opentelemetry/api@1.9.0':
+ resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
+ engines: {node: '>=8.0.0'}
+
+ '@phosphor-icons/core@2.1.1':
+ resolution: {integrity: sha512-v4ARvrip4qBCImOE5rmPUylOEK4iiED9ZyKjcvzuezqMaiRASCHKcRIuvvxL/twvLpkfnEODCOJp5dM4eZilxQ==}
+
+ '@radix-ui/react-compose-refs@1.1.2':
+ resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-slot@1.2.4':
+ resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@replit/codemirror-css-color-picker@6.3.0':
+ resolution: {integrity: sha512-19biDANghUm7Fz7L1SNMIhK48tagaWuCOHj4oPPxc7hxPGkTVY2lU/jVZ8tsbTKQPVG7BO2CBDzs7CBwb20t4A==}
+ peerDependencies:
+ '@codemirror/language': ^6.0.0
+ '@codemirror/state': ^6.0.0
+ '@codemirror/view': ^6.0.0
+
+ '@rolldown/pluginutils@1.0.0-rc.3':
+ resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==}
+
+ '@rollup/rollup-android-arm-eabi@4.60.3':
+ resolution: {integrity: sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.60.3':
+ resolution: {integrity: sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.60.3':
+ resolution: {integrity: sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.60.3':
+ resolution: {integrity: sha512-D+0QGcZhBzTN82weOnsSlY7V7+RMmPuF1CkbxyMAGE8+ZHeUjyb76ZiWmBlCu//AQQONvxcqRbwZTajZKqjuOw==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.60.3':
+ resolution: {integrity: sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.60.3':
+ resolution: {integrity: sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.60.3':
+ resolution: {integrity: sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.60.3':
+ resolution: {integrity: sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.60.3':
+ resolution: {integrity: sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.60.3':
+ resolution: {integrity: sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loong64-gnu@4.60.3':
+ resolution: {integrity: sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loong64-musl@4.60.3':
+ resolution: {integrity: sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-ppc64-gnu@4.60.3':
+ resolution: {integrity: sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-ppc64-musl@4.60.3':
+ resolution: {integrity: sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.60.3':
+ resolution: {integrity: sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-musl@4.60.3':
+ resolution: {integrity: sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-s390x-gnu@4.60.3':
+ resolution: {integrity: sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-gnu@4.60.3':
+ resolution: {integrity: sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-musl@4.60.3':
+ resolution: {integrity: sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-openbsd-x64@4.60.3':
+ resolution: {integrity: sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q==}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@rollup/rollup-openharmony-arm64@4.60.3':
+ resolution: {integrity: sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rollup/rollup-win32-arm64-msvc@4.60.3':
+ resolution: {integrity: sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.60.3':
+ resolution: {integrity: sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-gnu@4.60.3':
+ resolution: {integrity: sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A==}
+ cpu: [x64]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.60.3':
+ resolution: {integrity: sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA==}
+ cpu: [x64]
+ os: [win32]
+
+ '@scalar/agent-chat@0.10.14':
+ resolution: {integrity: sha512-b92iQVZt2aXG6jzfFrovOzoKkjuSIuMo8mLCuWuo6q/0GeQRkdLWz4DTaNBpaNv7J6AoptfGj8hAaA6W5PyRXw==}
+ engines: {node: '>=22'}
+
+ '@scalar/api-client@3.6.0':
+ resolution: {integrity: sha512-6W5c5BFAkCcwlQdhyhfSaVo4+Hfz8bZxjgLMl6HCgxBzjU2iiRPSPpkIB3+BGo+dxaIRCLoWXh/vTfYR+hA02w==}
+ engines: {node: '>=22'}
+
+ '@scalar/api-reference-react@0.9.33':
+ resolution: {integrity: sha512-fxR1FFLahw1uazyi/NVFos+4MsEcJNWWM+YecdgkwdTExJ/RGNPakAniFnAmgVOFbu1WWzQlpAMhebwVFrxb9Q==}
+ engines: {node: '>=22'}
+ peerDependencies:
+ react: ^18.0.0 || ^19.0.0
+
+ '@scalar/api-reference@1.55.2':
+ resolution: {integrity: sha512-/AUWMBOqBg1AgMewuat6/hm1GNA1pgxIISHCjfDh3/XpLRKSqYCS5VwjDYNe23sOrovWsh+h/D1YK6On3Pxfwg==}
+ engines: {node: '>=22'}
+
+ '@scalar/code-highlight@0.3.4':
+ resolution: {integrity: sha512-gGr3D8bfInwZDHsxamYIaG72Wr+kRNX8d4zcOflAfQJ0ZfvqoVbYhhkiSd6K+DLySItK9lWl/cgjJdtKWlT2ig==}
+ engines: {node: '>=22'}
+
+ '@scalar/components@0.24.2':
+ resolution: {integrity: sha512-Llht48QpeT2ju4fGZWItCvl3KgZLFuWt70Sfzak2JXNvqHkLNlnUYl8isEzwGcQFfhG/tCwVghCAAMwkjFSTXA==}
+ engines: {node: '>=22'}
+
+ '@scalar/helpers@0.6.0':
+ resolution: {integrity: sha512-pfSamAgBxqFeE8IpEG6uGkHlnPhY1CLeOTttV9+vKQbrBk5b7vvyTsUXv0Hz4kNU1TFrxcTTPE+Akn5S+jlTtQ==}
+ engines: {node: '>=22'}
+
+ '@scalar/icons@0.7.2':
+ resolution: {integrity: sha512-21L2y/D6oU7wZHHa9i6FK98cZ+XH4HX9+e69uNpvlp4awRUpz6ifNHOLlxI607bq+Yz4G313gnV0uyUHwZ/pig==}
+ engines: {node: '>=22'}
+
+ '@scalar/json-magic@0.12.12':
+ resolution: {integrity: sha512-F7q6mPlVdHntvEvlJPwzvA2E2fjxsNtMeSzODtcdhp4mdQndMqqxEhy0rKmRvk36Oka+9F/hl3EDG194BpNBGg==}
+ engines: {node: '>=22'}
+
+ '@scalar/oas-utils@0.15.2':
+ resolution: {integrity: sha512-7ngu7ieNO8YUfEYEXcrJBIBbytjoq8HIATOJqxykZvUz0Vm5ttOgONSaAOXB19gE6t5xUl4A156MkjenOEwK6Q==}
+ engines: {node: '>=22'}
+
+ '@scalar/openapi-types@0.8.0':
+ resolution: {integrity: sha512-WmaxVSfvY5K/TwcG2B2TU1WOe1As1uc2s7myswtP6dBlcjU3hM08SApxv/jmyGaCE8t4gO5BBhmHY4pDUfmr2g==}
+ engines: {node: '>=22'}
+
+ '@scalar/openapi-upgrader@0.2.7':
+ resolution: {integrity: sha512-sC/uLQOivfX+Oef2QhUpgmERL7KZc1z+hiYkcwZQaUyVOHh5e6OscW0skfzbxKPyJfQ6Ocv0Iom9wMToCGaAPw==}
+ engines: {node: '>=22'}
+
+ '@scalar/postman-to-openapi@0.7.5':
+ resolution: {integrity: sha512-H6cTuD28XXeqSP2SEjmsJDaMKC/a95Jxr10qYyLyZ3Tc8jzQO7iVDn04PXDUUsFGyQ74x1txWq2JlckV3CHaZQ==}
+ engines: {node: '>=22'}
+
+ '@scalar/sidebar@0.9.10':
+ resolution: {integrity: sha512-lQG775TDRAbHe/Y6BNDI53tb8Rhigq4n4mw2f83EuBy+6w8SQC4Ib81HZyPY0O+n3La0qyYuXOzl8douboATsg==}
+ engines: {node: '>=22'}
+
+ '@scalar/snippetz@0.9.6':
+ resolution: {integrity: sha512-s2Rso+qajyyf9DBzIgt+T3HZ1Ewx1W+YOUdYg1ldJhlXjBtn0q1w6gbnv4C2HHCgXRh/6YIzIj7eDUWK9K3+sQ==}
+ engines: {node: '>=22'}
+
+ '@scalar/themes@0.15.3':
+ resolution: {integrity: sha512-KIGMVglWKxVcdPsdjiXDgyAYhCh53w0qoKRG/cmfP+N4OwR0pk0WzFaMzBscu+sKoZ8SMvZqbXyODO5CBtyD3w==}
+ engines: {node: '>=22'}
+
+ '@scalar/typebox@0.1.3':
+ resolution: {integrity: sha512-lU055AUccECZMIfGA0z/C1StYmboAYIPJLDFBzOO81yXBi35Pxdq+I4fWX6iUZ8qcoHneiLGk9jAUM1rA93iEg==}
+
+ '@scalar/types@0.9.6':
+ resolution: {integrity: sha512-UaCQQcscFTJdxZREE8KhUdSJgaDlc44TZbmWcZffs4m1hzqOvEI7lEBS13iBpLq7/cxUXFgyJdecywvNqJ0PkA==}
+ engines: {node: '>=22'}
+
+ '@scalar/use-codemirror@0.14.11':
+ resolution: {integrity: sha512-5wtC4pUjzhy72j3aAueJg+fh9KflevJvXMn0YscsxiDTvqwIzeZcHe1N9VNtvzDXgLblEeBT6D0+Vs+boyExxg==}
+ engines: {node: '>=22'}
+
+ '@scalar/use-hooks@0.4.3':
+ resolution: {integrity: sha512-dhDWGwqtiVshrAv/bpJ9qPt2Mdbbqyqvtvl2Fau+S9iv7Trsc2XDbfBc40cckSj6EhajgR4EHiuCR0E4DyaveQ==}
+ engines: {node: '>=22'}
+
+ '@scalar/use-toasts@0.10.2':
+ resolution: {integrity: sha512-1iHQFbDXv0YQRp13aa63S5EcTJ5K8T0ocnLxk+nziloPrLjKt6jdRt6vOHsLSv5sm9kFKcVKNQTQgialmKCOGA==}
+ engines: {node: '>=22'}
+
+ '@scalar/validation@0.3.2':
+ resolution: {integrity: sha512-iepw5zfpne2mNsCQdN/pST4HEfGwp7LMTb/f1sRuIN25SEXbdeUDvZnk1eoEPxol2TgGJUR3QXfaHQ4f8p6wHw==}
+ engines: {node: '>=20'}
+
+ '@scalar/workspace-store@0.49.2':
+ resolution: {integrity: sha512-1kOWtqFUwx1EI0f9ceiD/5q3OOlu4ioS4oRi8f35NTEzVwDcf9RTzQuUuTSzFku47Iv6hdfTFpPm1y3TMr6j+Q==}
+ engines: {node: '>=22'}
+
+ '@standard-schema/spec@1.1.0':
+ resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
+
+ '@swc/helpers@0.5.21':
+ resolution: {integrity: sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==}
+
+ '@tailwindcss/node@4.2.4':
+ resolution: {integrity: sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==}
+
+ '@tailwindcss/oxide-android-arm64@4.2.4':
+ resolution: {integrity: sha512-e7MOr1SAn9U8KlZzPi1ZXGZHeC5anY36qjNwmZv9pOJ8E4Q6jmD1vyEHkQFmNOIN7twGPEMXRHmitN4zCMN03g==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [android]
+
+ '@tailwindcss/oxide-darwin-arm64@4.2.4':
+ resolution: {integrity: sha512-tSC/Kbqpz/5/o/C2sG7QvOxAKqyd10bq+ypZNf+9Fi2TvbVbv1zNpcEptcsU7DPROaSbVgUXmrzKhurFvo5eDg==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-darwin-x64@4.2.4':
+ resolution: {integrity: sha512-yPyUXn3yO/ufR6+Kzv0t4fCg2qNr90jxXc5QqBpjlPNd0NqyDXcmQb/6weunH/MEDXW5dhyEi+agTDiqa3WsGg==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-freebsd-x64@4.2.4':
+ resolution: {integrity: sha512-BoMIB4vMQtZsXdGLVc2z+P9DbETkiopogfWZKbWwM8b/1Vinbs4YcUwo+kM/KeLkX3Ygrf4/PsRndKaYhS8Eiw==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.4':
+ resolution: {integrity: sha512-7pIHBLTHYRAlS7V22JNuTh33yLH4VElwKtB3bwchK/UaKUPpQ0lPQiOWcbm4V3WP2I6fNIJ23vABIvoy2izdwA==}
+ engines: {node: '>= 20'}
+ cpu: [arm]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.2.4':
+ resolution: {integrity: sha512-+E4wxJ0ZGOzSH325reXTWB48l42i93kQqMvDyz5gqfRzRZ7faNhnmvlV4EPGJU3QJM/3Ab5jhJ5pCRUsKn6OQw==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.2.4':
+ resolution: {integrity: sha512-bBADEGAbo4ASnppIziaQJelekCxdMaxisrk+fB7Thit72IBnALp9K6ffA2G4ruj90G9XRS2VQ6q2bCKbfFV82g==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.2.4':
+ resolution: {integrity: sha512-7Mx25E4WTfnht0TVRTyC00j3i0M+EeFe7wguMDTlX4mRxafznw0CA8WJkFjWYH5BlgELd1kSjuU2JiPnNZbJDA==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-x64-musl@4.2.4':
+ resolution: {integrity: sha512-2wwJRF7nyhOR0hhHoChc04xngV3iS+akccHTGtz965FwF0up4b2lOdo6kI1EbDaEXKgvcrFBYcYQQ/rrnWFVfA==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [linux]
+
+ '@tailwindcss/oxide-wasm32-wasi@4.2.4':
+ resolution: {integrity: sha512-FQsqApeor8Fo6gUEklzmaa9994orJZZDBAlQpK2Mq+DslRKFJeD6AjHpBQ0kZFQohVr8o85PPh8eOy86VlSCmw==}
+ engines: {node: '>=14.0.0'}
+ cpu: [wasm32]
+ bundledDependencies:
+ - '@napi-rs/wasm-runtime'
+ - '@emnapi/core'
+ - '@emnapi/runtime'
+ - '@tybys/wasm-util'
+ - '@emnapi/wasi-threads'
+ - tslib
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.2.4':
+ resolution: {integrity: sha512-L9BXqxC4ToVgwMFqj3pmZRqyHEztulpUJzCxUtLjobMCzTPsGt1Fa9enKbOpY2iIyVtaHNeNvAK8ERP/64sqGQ==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.2.4':
+ resolution: {integrity: sha512-ESlKG0EpVJQwRjXDDa9rLvhEAh0mhP1sF7sap9dNZT0yyl9SAG6T7gdP09EH0vIv0UNTlo6jPWyujD6559fZvw==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [win32]
+
+ '@tailwindcss/oxide@4.2.4':
+ resolution: {integrity: sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q==}
+ engines: {node: '>= 20'}
+
+ '@tailwindcss/vite@4.2.4':
+ resolution: {integrity: sha512-pCvohwOCspk3ZFn6eJzrrX3g4n2JY73H6MmYC87XfGPyTty4YsCjYTMArRZm/zOI8dIt3+EcrLHAFPe5A4bgtw==}
+ peerDependencies:
+ vite: ^5.2.0 || ^6 || ^7 || ^8
+
+ '@tanstack/query-core@5.100.9':
+ resolution: {integrity: sha512-SJSFw1S8+kQ0+knv/XGfrbocWoAlT7vDKsSImtLx3ZPQmEcR46hkDjLSvynSy25N8Ms4tIEini1FuBd5k7IscQ==}
+
+ '@tanstack/react-query@5.100.9':
+ resolution: {integrity: sha512-Oa44XkaI3kCNN6ME0KByU3xT3SEUNOMfZpHxL6+wFoTm+OeUFYHKdeYVe0aOXlRDm/f15sgLwEt2HDorIdW8+A==}
+ peerDependencies:
+ react: ^18 || ^19
+
+ '@tanstack/virtual-core@3.14.0':
+ resolution: {integrity: sha512-JLANqGy/D6k4Ujmh8Tr25lGimuOXNiaVyXaCAZS0W+1390sADdGnyUdSWNIfd49gebtIxGMij4IktRVzrdr12Q==}
+
+ '@tanstack/vue-virtual@3.13.24':
+ resolution: {integrity: sha512-A0k2qF0zFSUStXSZkGXABouXr2Tw2Ztl/cVIYG9qy84uR8W7UNjAcX3DvzBS3YnDcwvLxab8v7dbmYBZ39itDA==}
+ peerDependencies:
+ vue: ^2.7.0 || ^3.0.0
+
+ '@types/babel__core@7.20.5':
+ resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
+
+ '@types/babel__generator@7.27.0':
+ resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==}
+
+ '@types/babel__template@7.4.4':
+ resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
+
+ '@types/babel__traverse@7.28.0':
+ resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==}
+
+ '@types/debug@4.1.13':
+ resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==}
+
+ '@types/estree@1.0.8':
+ resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
+
+ '@types/har-format@1.2.16':
+ resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==}
+
+ '@types/hast@3.0.4':
+ resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
+
+ '@types/mdast@4.0.4':
+ resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
+
+ '@types/ms@2.1.0':
+ resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
+
+ '@types/node@24.12.3':
+ resolution: {integrity: sha512-8oljBDGun9cIsZRJR6fkihn0TSXJI0UDOOhncYaERq6M0JMDoPLxyscwruJcb4GKS6dvK/d8xebYBg27h/duaQ==}
+
+ '@types/react-dom@19.2.3':
+ resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
+ peerDependencies:
+ '@types/react': ^19.2.0
+
+ '@types/react@19.2.14':
+ resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==}
+
+ '@types/trusted-types@2.0.7':
+ resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
+
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
+ '@types/web-bluetooth@0.0.20':
+ resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
+
+ '@types/web-bluetooth@0.0.21':
+ resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==}
+
+ '@ungap/structured-clone@1.3.1':
+ resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==}
+
+ '@unhead/vue@2.1.13':
+ resolution: {integrity: sha512-HYy0shaHRnLNW9r85gppO8IiGz0ONWVV3zGdlT8CQ0tbTwixznJCIiyqV4BSV1aIF1jJIye0pd1p/k6Eab8Z/A==}
+ peerDependencies:
+ vue: '>=3.5.18'
+
+ '@vercel/oidc@3.1.0':
+ resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==}
+ engines: {node: '>= 20'}
+
+ '@vitejs/plugin-react@5.2.0':
+ resolution: {integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ peerDependencies:
+ vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ '@vue-macros/common@3.1.2':
+ resolution: {integrity: sha512-h9t4ArDdniO9ekYHAD95t9AZcAbb19lEGK+26iAjUODOIJKmObDNBSe4+6ELQAA3vtYiFPPBtHh7+cQCKi3Dng==}
+ engines: {node: '>=20.19.0'}
+ peerDependencies:
+ vue: ^2.7.0 || ^3.2.25
+ peerDependenciesMeta:
+ vue:
+ optional: true
+
+ '@vue/compiler-core@3.5.33':
+ resolution: {integrity: sha512-3PZLQwFw4Za3TC8t0FvTy3wI16Kt+pmwcgNZca4Pj9iWL2E72a/gZlpBtAJvEdDMdCxdG/qq0C7PN0bsJuv0Rw==}
+
+ '@vue/compiler-dom@3.5.33':
+ resolution: {integrity: sha512-PXq0yrfCLzzL07rbXO4awtXY1Z06LG2eu6Adg3RJFa/j3Cii217XxxLXG22N330gw7GmALCY0Z8RgXEviwgpjA==}
+
+ '@vue/compiler-sfc@3.5.33':
+ resolution: {integrity: sha512-UTUvRO9cY+rROrx/pvN9P5Z7FgA6QGfokUCfhQE4EnmUj3rVnK+CHI0LsEO1pg+I7//iRYMUfcNcCPe7tg0CoA==}
+
+ '@vue/compiler-ssr@3.5.33':
+ resolution: {integrity: sha512-IErjYdnj1qIupG5xxiVIYiiRvDhGWV4zuh/RCrwfYpuL+HWQzeU6lCk/nF9r7olWMnjKxCAkOctT2qFWFkzb1A==}
+
+ '@vue/devtools-api@8.1.1':
+ resolution: {integrity: sha512-bsDMJ07b3GN1puVwJb/fyFnj/U2imyswK5UQVLZwVl7O05jDrt6BHxeG5XffmOOdasOj/bOmIjxJvGPxU7pcqw==}
+
+ '@vue/devtools-kit@8.1.1':
+ resolution: {integrity: sha512-gVBaBv++i+adg4JpH71k9ppl4soyR7Y2McEqO5YNgv0BI1kMZ7BDX5gnwkZ5COYgiCyhejZG+yGNrBAjj6Coqg==}
+
+ '@vue/devtools-shared@8.1.1':
+ resolution: {integrity: sha512-+h4ttmJYl/txpxHKaoZcaKpC+pvckgLzIDiSQlaQ7kKthKh8KuwoLW2D8hPJEnqKzXOvu15UHEoGyngAXCz0EQ==}
+
+ '@vue/reactivity@3.5.33':
+ resolution: {integrity: sha512-p8UfIqyIhb0rYGlSgSBV+lPhF2iUSBcRy7enhTmPqKWadHy9kcOFYF1AejYBP9P+avnd3OBbD49DU4pLWX/94A==}
+
+ '@vue/runtime-core@3.5.33':
+ resolution: {integrity: sha512-UpFF45RI9//a7rvq7RdOQblb4tup7hHG9QsmIrxkFQLzQ7R8/iNQ5LE15NhLZ1/WcHMU2b47u6P33CPUelHyIQ==}
+
+ '@vue/runtime-dom@3.5.33':
+ resolution: {integrity: sha512-IOxMsAOwquhfITgmOgaPYl7/j8gKUxUFoflRc+u4LxyD3+783xne8vNta1PONVCvCV9A0w7hkyEepINDqfO0tw==}
+
+ '@vue/server-renderer@3.5.33':
+ resolution: {integrity: sha512-0xylq/8/h44lVG0pZFknv1XIdEgymq2E9n59uTWJBG+dIgiT0TMCSsxrN7nO16Z0MU0MPjFcguBbZV8Itk52Hw==}
+ peerDependencies:
+ vue: 3.5.33
+
+ '@vue/shared@3.5.33':
+ resolution: {integrity: sha512-5vR2QIlmaLG77Ygd4pMP6+SGQ5yox9VhtnbDWTy9DzMzdmeLxZ1QqxrywEZ9sa1AVubfIJyaCG3ytyWU81ufcQ==}
+
+ '@vueuse/core@10.11.1':
+ resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==}
+
+ '@vueuse/core@13.9.0':
+ resolution: {integrity: sha512-ts3regBQyURfCE2BcytLqzm8+MmLlo5Ln/KLoxDVcsZ2gzIwVNnQpQOL/UKV8alUqjSZOlpFZcRNsLRqj+OzyA==}
+ peerDependencies:
+ vue: ^3.5.0
+
+ '@vueuse/integrations@13.9.0':
+ resolution: {integrity: sha512-SDobKBbPIOe0cVL7QxMzGkuUGHvWTdihi9zOrrWaWUgFKe15cwEcwfWmgrcNzjT6kHnNmWuTajPHoIzUjYNYYQ==}
+ peerDependencies:
+ async-validator: ^4
+ axios: ^1
+ change-case: ^5
+ drauu: ^0.4
+ focus-trap: ^7
+ fuse.js: ^7
+ idb-keyval: ^6
+ jwt-decode: ^4
+ nprogress: ^0.2
+ qrcode: ^1.5
+ sortablejs: ^1
+ universal-cookie: ^7 || ^8
+ vue: ^3.5.0
+ peerDependenciesMeta:
+ async-validator:
+ optional: true
+ axios:
+ optional: true
+ change-case:
+ optional: true
+ drauu:
+ optional: true
+ focus-trap:
+ optional: true
+ fuse.js:
+ optional: true
+ idb-keyval:
+ optional: true
+ jwt-decode:
+ optional: true
+ nprogress:
+ optional: true
+ qrcode:
+ optional: true
+ sortablejs:
+ optional: true
+ universal-cookie:
+ optional: true
+
+ '@vueuse/metadata@10.11.1':
+ resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==}
+
+ '@vueuse/metadata@13.9.0':
+ resolution: {integrity: sha512-1AFRvuiGphfF7yWixZa0KwjYH8ulyjDCC0aFgrGRz8+P4kvDFSdXLVfTk5xAN9wEuD1J6z4/myMoYbnHoX07zg==}
+
+ '@vueuse/shared@10.11.1':
+ resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==}
+
+ '@vueuse/shared@13.9.0':
+ resolution: {integrity: sha512-e89uuTLMh0U5cZ9iDpEI2senqPGfbPRTHM/0AaQkcxnpqjkZqDYP8rpfm7edOz8s+pOCOROEy1PIveSW8+fL5g==}
+ peerDependencies:
+ vue: ^3.5.0
+
+ acorn@8.16.0:
+ resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ ai@6.0.33:
+ resolution: {integrity: sha512-bVokbmy2E2QF6Efl+5hOJx5MRWoacZ/CZY/y1E+VcewknvGlgaiCzMu8Xgddz6ArFJjiMFNUPHKxAhIePE4rmg==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ zod: ^3.25.76 || ^4.1.8
+
+ aria-hidden@1.2.6:
+ resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
+ engines: {node: '>=10'}
+
+ ast-kit@2.2.0:
+ resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==}
+ engines: {node: '>=20.19.0'}
+
+ ast-walker-scope@0.8.3:
+ resolution: {integrity: sha512-cbdCP0PGOBq0ASG+sjnKIoYkWMKhhz+F/h9pRexUdX2Hd38+WOlBkRKlqkGOSm0YQpcFMQBJeK4WspUAkwsEdg==}
+ engines: {node: '>=20.19.0'}
+
+ bail@2.0.2:
+ resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
+
+ baseline-browser-mapping@2.10.27:
+ resolution: {integrity: sha512-zEs/ufmZoUd7WftKpKyXaT6RFxpQ5Qm9xytKRHvJfxFV9DFJkZph9RvJ1LcOUi0Z1ZVijMte65JbILeV+8QQEA==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ birpc@2.9.0:
+ resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==}
+
+ browserslist@4.28.2:
+ resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
+ caniuse-lite@1.0.30001792:
+ resolution: {integrity: sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==}
+
+ ccount@2.0.1:
+ resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+
+ chalk@5.6.2:
+ resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
+ engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
+
+ character-entities-html4@2.1.0:
+ resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
+
+ character-entities-legacy@3.0.0:
+ resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
+
+ character-entities@2.0.2:
+ resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
+
+ chokidar@5.0.0:
+ resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
+ engines: {node: '>= 20.19.0'}
+
+ class-variance-authority@0.7.1:
+ resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
+
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
+ comma-separated-tokens@2.0.3:
+ resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
+
+ confbox@0.1.8:
+ resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
+
+ confbox@0.2.4:
+ resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==}
+
+ convert-hrtime@5.0.0:
+ resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==}
+ engines: {node: '>=12'}
+
+ convert-source-map@2.0.0:
+ resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+
+ cookie@1.1.1:
+ resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
+ engines: {node: '>=18'}
+
+ crelt@1.0.6:
+ resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==}
+
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+
+ cva@1.0.0-beta.4:
+ resolution: {integrity: sha512-F/JS9hScapq4DBVQXcK85l9U91M6ePeXoBMSp7vypzShoefUBxjQTo3g3935PUHgQd+IW77DjbPRIxugy4/GCQ==}
+ peerDependencies:
+ typescript: '>= 4.5.5'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ decode-named-character-reference@1.3.0:
+ resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==}
+
+ defu@6.1.7:
+ resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==}
+
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
+ detect-libc@2.1.2:
+ resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+ engines: {node: '>=8'}
+
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
+ dompurify@3.2.7:
+ resolution: {integrity: sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==}
+
+ electron-to-chromium@1.5.352:
+ resolution: {integrity: sha512-9wHk8x6dyuimoe18EdiDPWKExNdxYqo4fn4FwOVVper6RxT3cmpBwBkWWfSOCYJjQdIco/nPhJhNLmn4Ufg1Yg==}
+
+ enhanced-resolve@5.21.2:
+ resolution: {integrity: sha512-xe9vQb5kReirPUxgQrXA3ihgbCqssmTiM7cOZ+Gzu+VeGWgpV98lLZvp0dl4yriyAePcewxGUs9UpKD8PET9KQ==}
+ engines: {node: '>=10.13.0'}
+
+ entities@6.0.1:
+ resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
+ engines: {node: '>=0.12'}
+
+ entities@7.0.1:
+ resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
+ engines: {node: '>=0.12'}
+
+ esbuild@0.27.7:
+ resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ escape-string-regexp@5.0.0:
+ resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
+ engines: {node: '>=12'}
+
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ eventsource-parser@3.0.8:
+ resolution: {integrity: sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==}
+ engines: {node: '>=18.0.0'}
+
+ exsolve@1.0.8:
+ resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==}
+
+ extend@3.0.2:
+ resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ flatted@3.4.2:
+ resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==}
+
+ focus-trap@7.8.0:
+ resolution: {integrity: sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ function-timeout@1.0.2:
+ resolution: {integrity: sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==}
+ engines: {node: '>=18'}
+
+ fuse.js@7.3.0:
+ resolution: {integrity: sha512-plz8RVjfcDedTGfVngWH1jmJvBvAwi1v2jecfDerbEnMcmOYUEEwKFTHbNoCiYyzaK2Ws8lABkTCcRSqCY1q4w==}
+ engines: {node: '>=10'}
+
+ gensync@1.0.0-beta.2:
+ resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
+ engines: {node: '>=6.9.0'}
+
+ get-own-enumerable-keys@1.0.0:
+ resolution: {integrity: sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==}
+ engines: {node: '>=14.16'}
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ guess-json-indent@3.0.1:
+ resolution: {integrity: sha512-LWZ3Vr8BG7DHE3TzPYFqkhjNRw4vYgFSsv2nfMuHklAlOfiy54/EwiDQuQfFVLxENCVv20wpbjfTayooQHrEhQ==}
+ engines: {node: '>=18.18.0'}
+
+ hast-util-embedded@3.0.0:
+ resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==}
+
+ hast-util-format@1.1.0:
+ resolution: {integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==}
+
+ hast-util-from-html@2.0.3:
+ resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==}
+
+ hast-util-from-parse5@8.0.3:
+ resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==}
+
+ hast-util-has-property@3.0.0:
+ resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==}
+
+ hast-util-is-body-ok-link@3.0.1:
+ resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==}
+
+ hast-util-is-element@3.0.0:
+ resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==}
+
+ hast-util-minify-whitespace@1.0.1:
+ resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==}
+
+ hast-util-parse-selector@4.0.0:
+ resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
+
+ hast-util-phrasing@3.0.1:
+ resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==}
+
+ hast-util-raw@9.1.0:
+ resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==}
+
+ hast-util-sanitize@5.0.2:
+ resolution: {integrity: sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==}
+
+ hast-util-to-html@9.0.5:
+ resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==}
+
+ hast-util-to-parse5@8.0.1:
+ resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==}
+
+ hast-util-to-text@4.0.2:
+ resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==}
+
+ hast-util-whitespace@3.0.0:
+ resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+
+ hastscript@9.0.1:
+ resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==}
+
+ highlight.js@11.11.1:
+ resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==}
+ engines: {node: '>=12.0.0'}
+
+ hookable@5.5.3:
+ resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
+
+ hookable@6.1.1:
+ resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==}
+
+ html-void-elements@3.0.0:
+ resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+
+ html-whitespace-sensitive-tag-names@3.0.1:
+ resolution: {integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==}
+
+ identifier-regex@1.0.1:
+ resolution: {integrity: sha512-ZrYyM0sozNPZlvBvE7Oq9Bn44n0qKGrYu5sQ0JzMUnjIhpgWYE2JB6aBoFwEYdPjqj7jPyxXTMJiHDOxDfd8yw==}
+ engines: {node: '>=18'}
+
+ is-absolute-url@4.0.1:
+ resolution: {integrity: sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ is-identifier@1.0.1:
+ resolution: {integrity: sha512-HQ5v4rEJ7REUV54bCd2l5FaD299SGDEn2UPoVXaTHAyGviLq2menVUD2udi3trQ32uvB6LdAh/0ck2EuizrtpA==}
+ engines: {node: '>=18'}
+
+ is-obj@3.0.0:
+ resolution: {integrity: sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==}
+ engines: {node: '>=12'}
+
+ is-plain-obj@4.1.0:
+ resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
+ engines: {node: '>=12'}
+
+ is-regexp@3.1.0:
+ resolution: {integrity: sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==}
+ engines: {node: '>=12'}
+
+ jiti@2.7.0:
+ resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
+ hasBin: true
+
+ js-base64@3.7.8:
+ resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==}
+
+ js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ jsesc@3.1.0:
+ resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ json-schema@0.4.0:
+ resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
+
+ json5@2.2.3:
+ resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ jsonc-parser@3.3.1:
+ resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==}
+
+ lightningcss-android-arm64@1.32.0:
+ resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [android]
+
+ lightningcss-darwin-arm64@1.32.0:
+ resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ lightningcss-darwin-x64@1.32.0:
+ resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ lightningcss-freebsd-x64@1.32.0:
+ resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ lightningcss-linux-arm-gnueabihf@1.32.0:
+ resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ lightningcss-linux-arm64-gnu@1.32.0:
+ resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-arm64-musl@1.32.0:
+ resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-x64-gnu@1.32.0:
+ resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-linux-x64-musl@1.32.0:
+ resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-win32-arm64-msvc@1.32.0:
+ resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ lightningcss-win32-x64-msvc@1.32.0:
+ resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ lightningcss@1.32.0:
+ resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
+ engines: {node: '>= 12.0.0'}
+
+ local-pkg@1.1.2:
+ resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==}
+ engines: {node: '>=14'}
+
+ longest-streak@3.1.0:
+ resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
+
+ lowlight@3.3.0:
+ resolution: {integrity: sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==}
+
+ lru-cache@5.1.1:
+ resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+
+ lucide-react@0.469.0:
+ resolution: {integrity: sha512-28vvUnnKQ/dBwiCQtwJw7QauYnE7yd2Cyp4tTTJpvglX4EMpbflcdBgrgToX2j71B3YvugK/NH3BGUk+E/p/Fw==}
+ peerDependencies:
+ react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
+ lucide-react@0.553.0:
+ resolution: {integrity: sha512-BRgX5zrWmNy/lkVAe0dXBgd7XQdZ3HTf+Hwe3c9WK6dqgnj9h+hxV+MDncM88xDWlCq27+TKvHGE70ViODNILw==}
+ peerDependencies:
+ react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
+ magic-string-ast@1.0.3:
+ resolution: {integrity: sha512-CvkkH1i81zl7mmb94DsRiFeG9V2fR2JeuK8yDgS8oiZSFa++wWLEgZ5ufEOyLHbvSbD1gTRKv9NdX69Rnvr9JA==}
+ engines: {node: '>=20.19.0'}
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ make-asynchronous@1.1.0:
+ resolution: {integrity: sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==}
+ engines: {node: '>=18'}
+
+ markdown-table@3.0.4:
+ resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
+
+ marked@14.0.0:
+ resolution: {integrity: sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==}
+ engines: {node: '>= 18'}
+ hasBin: true
+
+ mdast-util-find-and-replace@3.0.2:
+ resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==}
+
+ mdast-util-from-markdown@2.0.3:
+ resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==}
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==}
+
+ mdast-util-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==}
+
+ mdast-util-gfm-strikethrough@2.0.0:
+ resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==}
+
+ mdast-util-gfm-table@2.0.0:
+ resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==}
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==}
+
+ mdast-util-gfm@3.1.0:
+ resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==}
+
+ mdast-util-phrasing@4.1.0:
+ resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
+
+ mdast-util-to-hast@13.2.1:
+ resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==}
+
+ mdast-util-to-markdown@2.1.2:
+ resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==}
+
+ mdast-util-to-string@4.0.0:
+ resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
+
+ microdiff@1.5.0:
+ resolution: {integrity: sha512-Drq+/THMvDdzRYrK0oxJmOKiC24ayUV8ahrt8l3oRK51PWt6gdtrIGrlIH3pT/lFh1z93FbAcidtsHcWbnRz8Q==}
+
+ micromark-core-commonmark@2.0.3:
+ resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==}
+
+ micromark-extension-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==}
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==}
+
+ micromark-extension-gfm-table@2.1.1:
+ resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==}
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==}
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==}
+
+ micromark-extension-gfm@3.0.0:
+ resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==}
+
+ micromark-factory-destination@2.0.1:
+ resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==}
+
+ micromark-factory-label@2.0.1:
+ resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==}
+
+ micromark-factory-space@2.0.1:
+ resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==}
+
+ micromark-factory-title@2.0.1:
+ resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==}
+
+ micromark-factory-whitespace@2.0.1:
+ resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==}
+
+ micromark-util-character@2.1.1:
+ resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
+
+ micromark-util-chunked@2.0.1:
+ resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==}
+
+ micromark-util-classify-character@2.0.1:
+ resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==}
+
+ micromark-util-combine-extensions@2.0.1:
+ resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==}
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==}
+
+ micromark-util-decode-string@2.0.1:
+ resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==}
+
+ micromark-util-encode@2.0.1:
+ resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
+
+ micromark-util-html-tag-name@2.0.1:
+ resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==}
+
+ micromark-util-normalize-identifier@2.0.1:
+ resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==}
+
+ micromark-util-resolve-all@2.0.1:
+ resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==}
+
+ micromark-util-sanitize-uri@2.0.1:
+ resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
+
+ micromark-util-subtokenize@2.1.0:
+ resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==}
+
+ micromark-util-symbol@2.0.1:
+ resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
+
+ micromark-util-types@2.0.2:
+ resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==}
+
+ micromark@4.0.2:
+ resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==}
+
+ mlly@1.8.2:
+ resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==}
+
+ monaco-editor@0.55.1:
+ resolution: {integrity: sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==}
+
+ monaco-languageserver-types@0.4.0:
+ resolution: {integrity: sha512-QQ3BZiU5LYkJElGncSNb5AKoJ/LCs6YBMCJMAz9EA7v+JaOdn3kx2cXpPTcZfKA5AEsR0vc97sAw+5mdNhVBmw==}
+
+ monaco-marker-data-provider@1.2.5:
+ resolution: {integrity: sha512-5ZdcYukhPwgYMCvlZ9H5uWs5jc23BQ8fFF5AhSIdrz5mvYLsqGZ58ZLxTv8rCX6+AxdJ8+vxg1HVSk+F2bLosg==}
+
+ monaco-types@0.1.2:
+ resolution: {integrity: sha512-8LwfrlWXsedHwAL41xhXyqzPibS8IqPuIXr9NdORhonS495c2/wky+sI1PRLvMCuiI0nqC2NH1six9hdiRY4Xg==}
+
+ monaco-worker-manager@2.0.1:
+ resolution: {integrity: sha512-kdPL0yvg5qjhKPNVjJoym331PY/5JC11aPJXtCZNwWRvBr6jhkIamvYAyiY5P1AWFmNOy0aRDRoMdZfa71h8kg==}
+ peerDependencies:
+ monaco-editor: '>=0.30.0'
+
+ monaco-yaml@5.4.1:
+ resolution: {integrity: sha512-YQ6d/Ei98Uk073SJLFbwuSi95qhnl8F8NNmIUqN2XhDt9psZN2LqQ1T7pPQ866NJb2wFj44IrjnANgpa2jTfag==}
+ peerDependencies:
+ monaco-editor: '>=0.36'
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ muggle-string@0.4.1:
+ resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
+
+ nanoid@3.3.12:
+ resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ nanoid@5.1.11:
+ resolution: {integrity: sha512-v+KEsUv2ps74PaSKv0gHTxTCgMXOIfBEbaqa6w6ISIGC7ZsvHN4N9oJ8d4cmf0n5oTzQz2SLmThbQWhjd/8eKg==}
+ engines: {node: ^18 || >=20}
+ hasBin: true
+
+ neverpanic@0.0.7:
+ resolution: {integrity: sha512-GFRTSX2JAEATOCQYlyFkR+9FJPl0pD24toE1foqYAsL6aPLlRKn6L0UFOtJhZCxEbDv+SUsiW4AcPs9cIFwkFw==}
+ peerDependencies:
+ typescript: '5'
+
+ node-releases@2.0.38:
+ resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==}
+
+ p-event@6.0.1:
+ resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==}
+ engines: {node: '>=16.17'}
+
+ p-timeout@6.1.4:
+ resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==}
+ engines: {node: '>=14.16'}
+
+ parse-ms@4.0.0:
+ resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==}
+ engines: {node: '>=18'}
+
+ parse5@7.3.0:
+ resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
+
+ path-browserify@1.0.1:
+ resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
+
+ pathe@2.0.3:
+ resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+ perfect-debounce@2.1.0:
+ resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@4.0.4:
+ resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
+ engines: {node: '>=12'}
+
+ pkg-types@1.3.1:
+ resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
+
+ pkg-types@2.3.1:
+ resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==}
+
+ postcss@8.5.14:
+ resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ prettier@3.8.3:
+ resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==}
+ engines: {node: '>=14'}
+ hasBin: true
+
+ pretty-ms@9.3.0:
+ resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==}
+ engines: {node: '>=18'}
+
+ property-information@7.1.0:
+ resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
+
+ quansync@0.2.11:
+ resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==}
+
+ radix-vue@1.9.17:
+ resolution: {integrity: sha512-mVCu7I2vXt1L2IUYHTt0sZMz7s1K2ZtqKeTIxG3yC5mMFfLBG4FtE1FDeRMpDd+Hhg/ybi9+iXmAP1ISREndoQ==}
+ peerDependencies:
+ vue: '>= 3.2.0'
+
+ react-dom@19.2.6:
+ resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==}
+ peerDependencies:
+ react: ^19.2.6
+
+ react-refresh@0.18.0:
+ resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==}
+ engines: {node: '>=0.10.0'}
+
+ react@19.2.6:
+ resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==}
+ engines: {node: '>=0.10.0'}
+
+ readdirp@5.0.0:
+ resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==}
+ engines: {node: '>= 20.19.0'}
+
+ rehype-external-links@3.0.0:
+ resolution: {integrity: sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw==}
+
+ rehype-format@5.0.1:
+ resolution: {integrity: sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==}
+
+ rehype-parse@9.0.1:
+ resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==}
+
+ rehype-raw@7.0.0:
+ resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==}
+
+ rehype-sanitize@6.0.0:
+ resolution: {integrity: sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==}
+
+ rehype-stringify@10.0.1:
+ resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==}
+
+ remark-gfm@4.0.1:
+ resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==}
+
+ remark-parse@11.0.0:
+ resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
+
+ remark-rehype@11.1.2:
+ resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==}
+
+ remark-stringify@11.0.0:
+ resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
+
+ reserved-identifiers@1.2.0:
+ resolution: {integrity: sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==}
+ engines: {node: '>=18'}
+
+ rollup@4.60.3:
+ resolution: {integrity: sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ scheduler@0.27.0:
+ resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
+
+ scule@1.3.0:
+ resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
+
+ semver@6.3.1:
+ resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+ hasBin: true
+
+ set-cookie-parser@3.1.0:
+ resolution: {integrity: sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==}
+
+ shell-quote@1.8.3:
+ resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==}
+ engines: {node: '>= 0.4'}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ space-separated-tokens@2.0.2:
+ resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
+
+ string-byte-length@3.0.1:
+ resolution: {integrity: sha512-yJ8vP0HMwZ54CcA8S8mKoXbkezpZHANFtmafFo8lGxZThCQcAwRHjdFabuSLgOzxj9OFJcmssmiAvmcOK4O2Hw==}
+ engines: {node: '>=18.18.0'}
+
+ string-byte-slice@3.0.1:
+ resolution: {integrity: sha512-GWv2K4lYyd2+AhmKH3BV+OVx62xDX+99rSLfKpaqFiQU7uOMaUY1tDjdrRD4gsrCr9lTyjMgjna7tZcCOw+Smg==}
+ engines: {node: '>=18.18.0'}
+
+ stringify-entities@4.0.4:
+ resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
+
+ stringify-object@6.0.0:
+ resolution: {integrity: sha512-6f94vIED6vmJJfh3lyVsVWxCYSfI5uM+16ntED/Ql37XIyV6kj0mRAAiTeMMc/QLYIaizC3bUprQ8pQnDDrKfA==}
+ engines: {node: '>=20'}
+
+ style-mod@4.1.3:
+ resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==}
+
+ super-regex@1.1.0:
+ resolution: {integrity: sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==}
+ engines: {node: '>=18'}
+
+ swrv@1.2.0:
+ resolution: {integrity: sha512-lH/g4UcNyj+7lzK4eRGT4C68Q4EhQ6JtM9otPRIASfhhzfLWtbZPHcMuhuba7S9YVYuxkMUGImwMyGpfbkH07A==}
+ peerDependencies:
+ vue: '>=3.2.26 < 4'
+
+ tabbable@6.4.0:
+ resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==}
+
+ tagged-tag@1.0.0:
+ resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==}
+ engines: {node: '>=20'}
+
+ tailwind-merge@2.6.1:
+ resolution: {integrity: sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ==}
+
+ tailwind-merge@3.5.0:
+ resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==}
+
+ tailwindcss@4.2.4:
+ resolution: {integrity: sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA==}
+
+ tapable@2.3.3:
+ resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==}
+ engines: {node: '>=6'}
+
+ time-span@5.1.0:
+ resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==}
+ engines: {node: '>=12'}
+
+ tinyglobby@0.2.16:
+ resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==}
+ engines: {node: '>=12.0.0'}
+
+ trim-lines@3.0.1:
+ resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
+
+ trough@2.2.0:
+ resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
+
+ truncate-json@3.0.1:
+ resolution: {integrity: sha512-QVsbr1WhGLq2F0oDyYbqtOXcf3gcnL8C9H5EX8bBwAr8ZWvWGJzukpPrDrWgJMrNtgDbo74BIjI4kJu3q2xQWw==}
+ engines: {node: '>=18.18.0'}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ type-fest@4.41.0:
+ resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
+ engines: {node: '>=16'}
+
+ type-fest@5.6.0:
+ resolution: {integrity: sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==}
+ engines: {node: '>=20'}
+
+ typescript@5.9.3:
+ resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ ufo@1.6.4:
+ resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==}
+
+ undici-types@7.16.0:
+ resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
+
+ unhead@2.1.13:
+ resolution: {integrity: sha512-jO9M1sI6b2h/1KpIu4Jeu+ptumLmUKboRRLxys5pYHFeT+lqTzfNHbYUX9bxVDhC1FBszAGuWcUVlmvIPsah8Q==}
+
+ unified@11.0.5:
+ resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
+
+ unist-util-find-after@5.0.0:
+ resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==}
+
+ unist-util-is@6.0.1:
+ resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==}
+
+ unist-util-position@5.0.0:
+ resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+
+ unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+
+ unist-util-visit-parents@6.0.2:
+ resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==}
+
+ unist-util-visit@5.1.0:
+ resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==}
+
+ unplugin-utils@0.3.1:
+ resolution: {integrity: sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==}
+ engines: {node: '>=20.19.0'}
+
+ unplugin@3.0.0:
+ resolution: {integrity: sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+
+ update-browserslist-db@1.2.3:
+ resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
+ vfile-location@5.0.3:
+ resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
+
+ vfile-message@4.0.3:
+ resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
+
+ vfile@6.0.3:
+ resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+
+ vite-plugin-monaco-editor@1.1.0:
+ resolution: {integrity: sha512-IvtUqZotrRoVqwT0PBBDIZPNraya3BxN/bfcNfnxZ5rkJiGcNtO5eAOWWSgT7zullIAEqQwxMU83yL9J5k7gww==}
+ peerDependencies:
+ monaco-editor: '>=0.33.0'
+
+ vite@7.3.3:
+ resolution: {integrity: sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^20.19.0 || >=22.12.0
+ jiti: '>=1.21.0'
+ less: ^4.0.0
+ lightningcss: ^1.21.0
+ sass: ^1.70.0
+ sass-embedded: ^1.70.0
+ stylus: '>=0.54.8'
+ sugarss: ^5.0.0
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ vscode-jsonrpc@8.2.0:
+ resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==}
+ engines: {node: '>=14.0.0'}
+
+ vscode-languageserver-protocol@3.17.5:
+ resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==}
+
+ vscode-languageserver-textdocument@1.0.12:
+ resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==}
+
+ vscode-languageserver-types@3.17.5:
+ resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==}
+
+ vscode-uri@3.1.0:
+ resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
+
+ vue-component-type-helpers@3.2.8:
+ resolution: {integrity: sha512-9689efAXhN/EV86plgkL/XFiJSXhGtWPG6JDboZ+QnjlUWUUQrQ0ILKQtw4iQsuwIwu5k6Aw+JnehDe7161e7A==}
+
+ vue-demi@0.14.10:
+ resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
+ engines: {node: '>=12'}
+ hasBin: true
+ peerDependencies:
+ '@vue/composition-api': ^1.0.0-rc.1
+ vue: ^3.0.0-0 || ^2.6.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+
+ vue-router@5.0.4:
+ resolution: {integrity: sha512-lCqDLCI2+fKVRl2OzXuzdSWmxXFLQRxQbmHugnRpTMyYiT+hNaycV0faqG5FBHDXoYrZ6MQcX87BvbY8mQ20Bg==}
+ peerDependencies:
+ '@pinia/colada': '>=0.21.2'
+ '@vue/compiler-sfc': ^3.5.17
+ pinia: ^3.0.4
+ vue: ^3.5.0
+ peerDependenciesMeta:
+ '@pinia/colada':
+ optional: true
+ '@vue/compiler-sfc':
+ optional: true
+ pinia:
+ optional: true
+
+ vue-sonner@1.3.2:
+ resolution: {integrity: sha512-UbZ48E9VIya3ToiRHAZUbodKute/z/M1iT8/3fU8zEbwBRE11AKuHikssv18LMk2gTTr6eMQT4qf6JoLHWuj/A==}
+
+ vue@3.5.33:
+ resolution: {integrity: sha512-1AgChhx5w3ALgT4oK3acm2Es/7jyZhWSVUfs3rOBlGQC0rjEDkS7G4lWlJJGGNQD+BV3reCwbQrOe1mPNwKHBQ==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ w3c-keyname@2.2.8:
+ resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
+
+ web-namespaces@2.0.1:
+ resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
+
+ web-worker@1.5.0:
+ resolution: {integrity: sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==}
+
+ webpack-virtual-modules@0.6.2:
+ resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
+
+ yallist@3.1.1:
+ resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+
+ yaml@2.8.4:
+ resolution: {integrity: sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==}
+ engines: {node: '>= 14.6'}
+ hasBin: true
+
+ zod@4.4.3:
+ resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
+
+ zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+
+snapshots:
+
+ '@ai-sdk/gateway@3.0.13(zod@4.4.3)':
+ dependencies:
+ '@ai-sdk/provider': 3.0.2
+ '@ai-sdk/provider-utils': 4.0.5(zod@4.4.3)
+ '@vercel/oidc': 3.1.0
+ zod: 4.4.3
+
+ '@ai-sdk/provider-utils@4.0.5(zod@4.4.3)':
+ dependencies:
+ '@ai-sdk/provider': 3.0.2
+ '@standard-schema/spec': 1.1.0
+ eventsource-parser: 3.0.8
+ zod: 4.4.3
+
+ '@ai-sdk/provider@3.0.2':
+ dependencies:
+ json-schema: 0.4.0
+
+ '@ai-sdk/vue@3.0.33(vue@3.5.33(typescript@5.9.3))(zod@4.4.3)':
+ dependencies:
+ '@ai-sdk/provider-utils': 4.0.5(zod@4.4.3)
+ ai: 6.0.33(zod@4.4.3)
+ swrv: 1.2.0(vue@3.5.33(typescript@5.9.3))
+ vue: 3.5.33(typescript@5.9.3)
+ transitivePeerDependencies:
+ - zod
+
+ '@babel/code-frame@7.29.0':
+ dependencies:
+ '@babel/helper-validator-identifier': 7.28.5
+ js-tokens: 4.0.0
+ picocolors: 1.1.1
+
+ '@babel/compat-data@7.29.3': {}
+
+ '@babel/core@7.29.0':
+ dependencies:
+ '@babel/code-frame': 7.29.0
+ '@babel/generator': 7.29.1
+ '@babel/helper-compilation-targets': 7.28.6
+ '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0)
+ '@babel/helpers': 7.29.2
+ '@babel/parser': 7.29.3
+ '@babel/template': 7.28.6
+ '@babel/traverse': 7.29.0
+ '@babel/types': 7.29.0
+ '@jridgewell/remapping': 2.3.5
+ convert-source-map: 2.0.0
+ debug: 4.4.3
+ gensync: 1.0.0-beta.2
+ json5: 2.2.3
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/generator@7.29.1':
+ dependencies:
+ '@babel/parser': 7.29.3
+ '@babel/types': 7.29.0
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+ jsesc: 3.1.0
+
+ '@babel/helper-compilation-targets@7.28.6':
+ dependencies:
+ '@babel/compat-data': 7.29.3
+ '@babel/helper-validator-option': 7.27.1
+ browserslist: 4.28.2
+ lru-cache: 5.1.1
+ semver: 6.3.1
+
+ '@babel/helper-globals@7.28.0': {}
+
+ '@babel/helper-module-imports@7.28.6':
+ dependencies:
+ '@babel/traverse': 7.29.0
+ '@babel/types': 7.29.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-module-imports': 7.28.6
+ '@babel/helper-validator-identifier': 7.28.5
+ '@babel/traverse': 7.29.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-plugin-utils@7.28.6': {}
+
+ '@babel/helper-string-parser@7.27.1': {}
+
+ '@babel/helper-validator-identifier@7.28.5': {}
+
+ '@babel/helper-validator-option@7.27.1': {}
+
+ '@babel/helpers@7.29.2':
+ dependencies:
+ '@babel/template': 7.28.6
+ '@babel/types': 7.29.0
+
+ '@babel/parser@7.29.3':
+ dependencies:
+ '@babel/types': 7.29.0
+
+ '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/template@7.28.6':
+ dependencies:
+ '@babel/code-frame': 7.29.0
+ '@babel/parser': 7.29.3
+ '@babel/types': 7.29.0
+
+ '@babel/traverse@7.29.0':
+ dependencies:
+ '@babel/code-frame': 7.29.0
+ '@babel/generator': 7.29.1
+ '@babel/helper-globals': 7.28.0
+ '@babel/parser': 7.29.3
+ '@babel/template': 7.28.6
+ '@babel/types': 7.29.0
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/types@7.29.0':
+ dependencies:
+ '@babel/helper-string-parser': 7.27.1
+ '@babel/helper-validator-identifier': 7.28.5
+
+ '@codemirror/autocomplete@6.20.1':
+ dependencies:
+ '@codemirror/language': 6.12.3
+ '@codemirror/state': 6.6.0
+ '@codemirror/view': 6.41.1
+ '@lezer/common': 1.5.2
+
+ '@codemirror/commands@6.10.3':
+ dependencies:
+ '@codemirror/language': 6.12.3
+ '@codemirror/state': 6.6.0
+ '@codemirror/view': 6.41.1
+ '@lezer/common': 1.5.2
+
+ '@codemirror/lang-css@6.3.1':
+ dependencies:
+ '@codemirror/autocomplete': 6.20.1
+ '@codemirror/language': 6.12.3
+ '@codemirror/state': 6.6.0
+ '@lezer/common': 1.5.2
+ '@lezer/css': 1.3.3
+
+ '@codemirror/lang-html@6.4.11':
+ dependencies:
+ '@codemirror/autocomplete': 6.20.1
+ '@codemirror/lang-css': 6.3.1
+ '@codemirror/lang-javascript': 6.2.5
+ '@codemirror/language': 6.12.3
+ '@codemirror/state': 6.6.0
+ '@codemirror/view': 6.41.1
+ '@lezer/common': 1.5.2
+ '@lezer/css': 1.3.3
+ '@lezer/html': 1.3.13
+
+ '@codemirror/lang-javascript@6.2.5':
+ dependencies:
+ '@codemirror/autocomplete': 6.20.1
+ '@codemirror/language': 6.12.3
+ '@codemirror/lint': 6.9.5
+ '@codemirror/state': 6.6.0
+ '@codemirror/view': 6.41.1
+ '@lezer/common': 1.5.2
+ '@lezer/javascript': 1.5.4
+
+ '@codemirror/lang-json@6.0.2':
+ dependencies:
+ '@codemirror/language': 6.12.3
+ '@lezer/json': 1.0.3
+
+ '@codemirror/lang-xml@6.1.0':
+ dependencies:
+ '@codemirror/autocomplete': 6.20.1
+ '@codemirror/language': 6.12.3
+ '@codemirror/state': 6.6.0
+ '@codemirror/view': 6.41.1
+ '@lezer/common': 1.5.2
+ '@lezer/xml': 1.0.6
+
+ '@codemirror/lang-yaml@6.1.3':
+ dependencies:
+ '@codemirror/autocomplete': 6.20.1
+ '@codemirror/language': 6.12.3
+ '@codemirror/state': 6.6.0
+ '@lezer/common': 1.5.2
+ '@lezer/highlight': 1.2.3
+ '@lezer/lr': 1.4.10
+ '@lezer/yaml': 1.0.4
+
+ '@codemirror/language@6.12.3':
+ dependencies:
+ '@codemirror/state': 6.6.0
+ '@codemirror/view': 6.41.1
+ '@lezer/common': 1.5.2
+ '@lezer/highlight': 1.2.3
+ '@lezer/lr': 1.4.10
+ style-mod: 4.1.3
+
+ '@codemirror/lint@6.9.5':
+ dependencies:
+ '@codemirror/state': 6.6.0
+ '@codemirror/view': 6.41.1
+ crelt: 1.0.6
+
+ '@codemirror/state@6.6.0':
+ dependencies:
+ '@marijn/find-cluster-break': 1.0.2
+
+ '@codemirror/view@6.41.1':
+ dependencies:
+ '@codemirror/state': 6.6.0
+ crelt: 1.0.6
+ style-mod: 4.1.3
+ w3c-keyname: 2.2.8
+
+ '@esbuild/aix-ppc64@0.27.7':
+ optional: true
+
+ '@esbuild/android-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/android-arm@0.27.7':
+ optional: true
+
+ '@esbuild/android-x64@0.27.7':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/darwin-x64@0.27.7':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-arm@0.27.7':
+ optional: true
+
+ '@esbuild/linux-ia32@0.27.7':
+ optional: true
+
+ '@esbuild/linux-loong64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.27.7':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-s390x@0.27.7':
+ optional: true
+
+ '@esbuild/linux-x64@0.27.7':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.27.7':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.27.7':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/sunos-x64@0.27.7':
+ optional: true
+
+ '@esbuild/win32-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/win32-ia32@0.27.7':
+ optional: true
+
+ '@esbuild/win32-x64@0.27.7':
+ optional: true
+
+ '@flanksource/clicky-ui@0.2.1(@tanstack/react-query@5.100.9(react@19.2.6))(@types/react@19.2.14)(@vue/compiler-sfc@3.5.33)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(tailwindcss@4.2.4)(typescript@5.9.3)':
+ dependencies:
+ '@iconify/react': 5.2.1(react@19.2.6)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6)
+ '@radix-ui/react-slot': 1.2.4(@types/react@19.2.14)(react@19.2.6)
+ '@scalar/api-reference-react': 0.9.33(@vue/compiler-sfc@3.5.33)(react@19.2.6)(tailwindcss@4.2.4)(typescript@5.9.3)
+ class-variance-authority: 0.7.1
+ clsx: 2.1.1
+ lucide-react: 0.469.0(react@19.2.6)
+ react: 19.2.6
+ react-dom: 19.2.6(react@19.2.6)
+ tailwind-merge: 2.6.1
+ tailwindcss: 4.2.4
+ optionalDependencies:
+ '@tanstack/react-query': 5.100.9(react@19.2.6)
+ transitivePeerDependencies:
+ - '@pinia/colada'
+ - '@types/react'
+ - '@vue/compiler-sfc'
+ - '@vue/composition-api'
+ - async-validator
+ - axios
+ - change-case
+ - drauu
+ - idb-keyval
+ - jwt-decode
+ - nprogress
+ - pinia
+ - qrcode
+ - sortablejs
+ - supports-color
+ - typescript
+ - universal-cookie
+
+ '@floating-ui/core@1.7.5':
+ dependencies:
+ '@floating-ui/utils': 0.2.11
+
+ '@floating-ui/dom@1.7.6':
+ dependencies:
+ '@floating-ui/core': 1.7.5
+ '@floating-ui/utils': 0.2.11
+
+ '@floating-ui/utils@0.2.10': {}
+
+ '@floating-ui/utils@0.2.11': {}
+
+ '@floating-ui/vue@1.1.11(vue@3.5.33(typescript@5.9.3))':
+ dependencies:
+ '@floating-ui/dom': 1.7.6
+ '@floating-ui/utils': 0.2.11
+ vue-demi: 0.14.10(vue@3.5.33(typescript@5.9.3))
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@floating-ui/vue@1.1.9(vue@3.5.33(typescript@5.9.3))':
+ dependencies:
+ '@floating-ui/dom': 1.7.6
+ '@floating-ui/utils': 0.2.10
+ vue-demi: 0.14.10(vue@3.5.33(typescript@5.9.3))
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@headlessui/tailwindcss@0.2.2(tailwindcss@4.2.4)':
+ dependencies:
+ tailwindcss: 4.2.4
+
+ '@headlessui/vue@1.7.23(vue@3.5.33(typescript@5.9.3))':
+ dependencies:
+ '@tanstack/vue-virtual': 3.13.24(vue@3.5.33(typescript@5.9.3))
+ vue: 3.5.33(typescript@5.9.3)
+
+ '@iconify/react@5.2.1(react@19.2.6)':
+ dependencies:
+ '@iconify/types': 2.0.0
+ react: 19.2.6
+
+ '@iconify/types@2.0.0': {}
+
+ '@internationalized/date@3.12.1':
+ dependencies:
+ '@swc/helpers': 0.5.21
+
+ '@internationalized/number@3.6.6':
+ dependencies:
+ '@swc/helpers': 0.5.21
+
+ '@jridgewell/gen-mapping@0.3.13':
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/remapping@2.3.5':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ '@lezer/common@1.5.2': {}
+
+ '@lezer/css@1.3.3':
+ dependencies:
+ '@lezer/common': 1.5.2
+ '@lezer/highlight': 1.2.3
+ '@lezer/lr': 1.4.10
+
+ '@lezer/highlight@1.2.3':
+ dependencies:
+ '@lezer/common': 1.5.2
+
+ '@lezer/html@1.3.13':
+ dependencies:
+ '@lezer/common': 1.5.2
+ '@lezer/highlight': 1.2.3
+ '@lezer/lr': 1.4.10
+
+ '@lezer/javascript@1.5.4':
+ dependencies:
+ '@lezer/common': 1.5.2
+ '@lezer/highlight': 1.2.3
+ '@lezer/lr': 1.4.10
+
+ '@lezer/json@1.0.3':
+ dependencies:
+ '@lezer/common': 1.5.2
+ '@lezer/highlight': 1.2.3
+ '@lezer/lr': 1.4.10
+
+ '@lezer/lr@1.4.10':
+ dependencies:
+ '@lezer/common': 1.5.2
+
+ '@lezer/xml@1.0.6':
+ dependencies:
+ '@lezer/common': 1.5.2
+ '@lezer/highlight': 1.2.3
+ '@lezer/lr': 1.4.10
+
+ '@lezer/yaml@1.0.4':
+ dependencies:
+ '@lezer/common': 1.5.2
+ '@lezer/highlight': 1.2.3
+ '@lezer/lr': 1.4.10
+
+ '@marijn/find-cluster-break@1.0.2': {}
+
+ '@opentelemetry/api@1.9.0': {}
+
+ '@phosphor-icons/core@2.1.1': {}
+
+ '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+ optionalDependencies:
+ '@types/react': 19.2.14
+
+ '@radix-ui/react-slot@1.2.4(@types/react@19.2.14)(react@19.2.6)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6)
+ react: 19.2.6
+ optionalDependencies:
+ '@types/react': 19.2.14
+
+ '@replit/codemirror-css-color-picker@6.3.0(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.41.1)':
+ dependencies:
+ '@codemirror/language': 6.12.3
+ '@codemirror/state': 6.6.0
+ '@codemirror/view': 6.41.1
+
+ '@rolldown/pluginutils@1.0.0-rc.3': {}
+
+ '@rollup/rollup-android-arm-eabi@4.60.3':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.60.3':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.60.3':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.60.3':
+ optional: true
+
+ '@rollup/rollup-freebsd-arm64@4.60.3':
+ optional: true
+
+ '@rollup/rollup-freebsd-x64@4.60.3':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.60.3':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.60.3':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.60.3':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.60.3':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-gnu@4.60.3':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-musl@4.60.3':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-gnu@4.60.3':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-musl@4.60.3':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.60.3':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-musl@4.60.3':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.60.3':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.60.3':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.60.3':
+ optional: true
+
+ '@rollup/rollup-openbsd-x64@4.60.3':
+ optional: true
+
+ '@rollup/rollup-openharmony-arm64@4.60.3':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.60.3':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.60.3':
+ optional: true
+
+ '@rollup/rollup-win32-x64-gnu@4.60.3':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.60.3':
+ optional: true
+
+ '@scalar/agent-chat@0.10.14(@vue/compiler-sfc@3.5.33)(tailwindcss@4.2.4)(typescript@5.9.3)':
+ dependencies:
+ '@ai-sdk/vue': 3.0.33(vue@3.5.33(typescript@5.9.3))(zod@4.4.3)
+ '@scalar/api-client': 3.6.0(@vue/compiler-sfc@3.5.33)(tailwindcss@4.2.4)(typescript@5.9.3)
+ '@scalar/components': 0.24.2(tailwindcss@4.2.4)(typescript@5.9.3)
+ '@scalar/helpers': 0.6.0
+ '@scalar/icons': 0.7.2(typescript@5.9.3)
+ '@scalar/json-magic': 0.12.12
+ '@scalar/openapi-types': 0.8.0
+ '@scalar/themes': 0.15.3
+ '@scalar/types': 0.9.6
+ '@scalar/use-toasts': 0.10.2(typescript@5.9.3)
+ '@scalar/workspace-store': 0.49.2(typescript@5.9.3)
+ '@vueuse/core': 13.9.0(vue@3.5.33(typescript@5.9.3))
+ ai: 6.0.33(zod@4.4.3)
+ js-base64: 3.7.8
+ neverpanic: 0.0.7(typescript@5.9.3)
+ truncate-json: 3.0.1
+ vue: 3.5.33(typescript@5.9.3)
+ zod: 4.4.3
+ transitivePeerDependencies:
+ - '@pinia/colada'
+ - '@vue/compiler-sfc'
+ - '@vue/composition-api'
+ - async-validator
+ - axios
+ - change-case
+ - drauu
+ - idb-keyval
+ - jwt-decode
+ - nprogress
+ - pinia
+ - qrcode
+ - sortablejs
+ - supports-color
+ - tailwindcss
+ - typescript
+ - universal-cookie
+
+ '@scalar/api-client@3.6.0(@vue/compiler-sfc@3.5.33)(tailwindcss@4.2.4)(typescript@5.9.3)':
+ dependencies:
+ '@headlessui/tailwindcss': 0.2.2(tailwindcss@4.2.4)
+ '@headlessui/vue': 1.7.23(vue@3.5.33(typescript@5.9.3))
+ '@scalar/components': 0.24.2(tailwindcss@4.2.4)(typescript@5.9.3)
+ '@scalar/helpers': 0.6.0
+ '@scalar/icons': 0.7.2(typescript@5.9.3)
+ '@scalar/json-magic': 0.12.12
+ '@scalar/oas-utils': 0.15.2(typescript@5.9.3)
+ '@scalar/openapi-types': 0.8.0
+ '@scalar/postman-to-openapi': 0.7.5
+ '@scalar/sidebar': 0.9.10(tailwindcss@4.2.4)(typescript@5.9.3)
+ '@scalar/snippetz': 0.9.6
+ '@scalar/themes': 0.15.3
+ '@scalar/typebox': 0.1.3
+ '@scalar/types': 0.9.6
+ '@scalar/use-codemirror': 0.14.11(typescript@5.9.3)
+ '@scalar/use-hooks': 0.4.3(typescript@5.9.3)
+ '@scalar/use-toasts': 0.10.2(typescript@5.9.3)
+ '@scalar/validation': 0.3.2
+ '@scalar/workspace-store': 0.49.2(typescript@5.9.3)
+ '@types/har-format': 1.2.16
+ '@vueuse/core': 13.9.0(vue@3.5.33(typescript@5.9.3))
+ '@vueuse/integrations': 13.9.0(focus-trap@7.8.0)(fuse.js@7.3.0)(vue@3.5.33(typescript@5.9.3))
+ cookie: 1.1.1
+ focus-trap: 7.8.0
+ fuse.js: 7.3.0
+ js-base64: 3.7.8
+ monaco-editor: 0.55.1
+ monaco-yaml: 5.4.1(monaco-editor@0.55.1)
+ nanoid: 5.1.11
+ pretty-ms: 9.3.0
+ radix-vue: 1.9.17(vue@3.5.33(typescript@5.9.3))
+ set-cookie-parser: 3.1.0
+ shell-quote: 1.8.3
+ vite-plugin-monaco-editor: 1.1.0(monaco-editor@0.55.1)
+ vue: 3.5.33(typescript@5.9.3)
+ vue-router: 5.0.4(@vue/compiler-sfc@3.5.33)(vue@3.5.33(typescript@5.9.3))
+ yaml: 2.8.4
+ zod: 4.4.3
+ transitivePeerDependencies:
+ - '@pinia/colada'
+ - '@vue/compiler-sfc'
+ - '@vue/composition-api'
+ - async-validator
+ - axios
+ - change-case
+ - drauu
+ - idb-keyval
+ - jwt-decode
+ - nprogress
+ - pinia
+ - qrcode
+ - sortablejs
+ - supports-color
+ - tailwindcss
+ - typescript
+ - universal-cookie
+
+ '@scalar/api-reference-react@0.9.33(@vue/compiler-sfc@3.5.33)(react@19.2.6)(tailwindcss@4.2.4)(typescript@5.9.3)':
+ dependencies:
+ '@scalar/api-reference': 1.55.2(@vue/compiler-sfc@3.5.33)(tailwindcss@4.2.4)(typescript@5.9.3)
+ '@scalar/types': 0.9.6
+ react: 19.2.6
+ transitivePeerDependencies:
+ - '@pinia/colada'
+ - '@vue/compiler-sfc'
+ - '@vue/composition-api'
+ - async-validator
+ - axios
+ - change-case
+ - drauu
+ - idb-keyval
+ - jwt-decode
+ - nprogress
+ - pinia
+ - qrcode
+ - sortablejs
+ - supports-color
+ - tailwindcss
+ - typescript
+ - universal-cookie
+
+ '@scalar/api-reference@1.55.2(@vue/compiler-sfc@3.5.33)(tailwindcss@4.2.4)(typescript@5.9.3)':
+ dependencies:
+ '@headlessui/vue': 1.7.23(vue@3.5.33(typescript@5.9.3))
+ '@scalar/agent-chat': 0.10.14(@vue/compiler-sfc@3.5.33)(tailwindcss@4.2.4)(typescript@5.9.3)
+ '@scalar/api-client': 3.6.0(@vue/compiler-sfc@3.5.33)(tailwindcss@4.2.4)(typescript@5.9.3)
+ '@scalar/code-highlight': 0.3.4
+ '@scalar/components': 0.24.2(tailwindcss@4.2.4)(typescript@5.9.3)
+ '@scalar/helpers': 0.6.0
+ '@scalar/icons': 0.7.2(typescript@5.9.3)
+ '@scalar/oas-utils': 0.15.2(typescript@5.9.3)
+ '@scalar/sidebar': 0.9.10(tailwindcss@4.2.4)(typescript@5.9.3)
+ '@scalar/snippetz': 0.9.6
+ '@scalar/themes': 0.15.3
+ '@scalar/types': 0.9.6
+ '@scalar/use-hooks': 0.4.3(typescript@5.9.3)
+ '@scalar/use-toasts': 0.10.2(typescript@5.9.3)
+ '@scalar/workspace-store': 0.49.2(typescript@5.9.3)
+ '@unhead/vue': 2.1.13(vue@3.5.33(typescript@5.9.3))
+ '@vueuse/core': 13.9.0(vue@3.5.33(typescript@5.9.3))
+ fuse.js: 7.3.0
+ microdiff: 1.5.0
+ nanoid: 5.1.11
+ vue: 3.5.33(typescript@5.9.3)
+ yaml: 2.8.4
+ transitivePeerDependencies:
+ - '@pinia/colada'
+ - '@vue/compiler-sfc'
+ - '@vue/composition-api'
+ - async-validator
+ - axios
+ - change-case
+ - drauu
+ - idb-keyval
+ - jwt-decode
+ - nprogress
+ - pinia
+ - qrcode
+ - sortablejs
+ - supports-color
+ - tailwindcss
+ - typescript
+ - universal-cookie
+
+ '@scalar/code-highlight@0.3.4':
+ dependencies:
+ hast-util-to-text: 4.0.2
+ highlight.js: 11.11.1
+ lowlight: 3.3.0
+ rehype-external-links: 3.0.0
+ rehype-format: 5.0.1
+ rehype-parse: 9.0.1
+ rehype-raw: 7.0.0
+ rehype-sanitize: 6.0.0
+ rehype-stringify: 10.0.1
+ remark-gfm: 4.0.1
+ remark-parse: 11.0.0
+ remark-rehype: 11.1.2
+ remark-stringify: 11.0.0
+ unified: 11.0.5
+ unist-util-visit: 5.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@scalar/components@0.24.2(tailwindcss@4.2.4)(typescript@5.9.3)':
+ dependencies:
+ '@floating-ui/utils': 0.2.10
+ '@floating-ui/vue': 1.1.9(vue@3.5.33(typescript@5.9.3))
+ '@headlessui/tailwindcss': 0.2.2(tailwindcss@4.2.4)
+ '@headlessui/vue': 1.7.23(vue@3.5.33(typescript@5.9.3))
+ '@scalar/code-highlight': 0.3.4
+ '@scalar/helpers': 0.6.0
+ '@scalar/icons': 0.7.2(typescript@5.9.3)
+ '@scalar/themes': 0.15.3
+ '@scalar/use-hooks': 0.4.3(typescript@5.9.3)
+ '@vueuse/core': 13.9.0(vue@3.5.33(typescript@5.9.3))
+ cva: 1.0.0-beta.4(typescript@5.9.3)
+ nanoid: 5.1.11
+ radix-vue: 1.9.17(vue@3.5.33(typescript@5.9.3))
+ vue: 3.5.33(typescript@5.9.3)
+ vue-component-type-helpers: 3.2.8
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - supports-color
+ - tailwindcss
+ - typescript
+
+ '@scalar/helpers@0.6.0': {}
+
+ '@scalar/icons@0.7.2(typescript@5.9.3)':
+ dependencies:
+ '@phosphor-icons/core': 2.1.1
+ '@types/node': 24.12.3
+ chalk: 5.6.2
+ vue: 3.5.33(typescript@5.9.3)
+ transitivePeerDependencies:
+ - typescript
+
+ '@scalar/json-magic@0.12.12':
+ dependencies:
+ '@scalar/helpers': 0.6.0
+ pathe: 2.0.3
+ yaml: 2.8.4
+
+ '@scalar/oas-utils@0.15.2(typescript@5.9.3)':
+ dependencies:
+ '@scalar/helpers': 0.6.0
+ '@scalar/themes': 0.15.3
+ '@scalar/types': 0.9.6
+ '@scalar/workspace-store': 0.49.2(typescript@5.9.3)
+ flatted: 3.4.2
+ vue: 3.5.33(typescript@5.9.3)
+ yaml: 2.8.4
+ transitivePeerDependencies:
+ - typescript
+
+ '@scalar/openapi-types@0.8.0': {}
+
+ '@scalar/openapi-upgrader@0.2.7':
+ dependencies:
+ '@scalar/openapi-types': 0.8.0
+
+ '@scalar/postman-to-openapi@0.7.5':
+ dependencies:
+ '@scalar/helpers': 0.6.0
+ '@scalar/openapi-types': 0.8.0
+
+ '@scalar/sidebar@0.9.10(tailwindcss@4.2.4)(typescript@5.9.3)':
+ dependencies:
+ '@scalar/components': 0.24.2(tailwindcss@4.2.4)(typescript@5.9.3)
+ '@scalar/helpers': 0.6.0
+ '@scalar/icons': 0.7.2(typescript@5.9.3)
+ '@scalar/themes': 0.15.3
+ '@scalar/use-hooks': 0.4.3(typescript@5.9.3)
+ '@scalar/workspace-store': 0.49.2(typescript@5.9.3)
+ vue: 3.5.33(typescript@5.9.3)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - supports-color
+ - tailwindcss
+ - typescript
+
+ '@scalar/snippetz@0.9.6':
+ dependencies:
+ '@scalar/types': 0.9.6
+ js-base64: 3.7.8
+ stringify-object: 6.0.0
+
+ '@scalar/themes@0.15.3':
+ dependencies:
+ nanoid: 5.1.11
+
+ '@scalar/typebox@0.1.3': {}
+
+ '@scalar/types@0.9.6':
+ dependencies:
+ '@scalar/helpers': 0.6.0
+ nanoid: 5.1.11
+ type-fest: 5.6.0
+ zod: 4.4.3
+
+ '@scalar/use-codemirror@0.14.11(typescript@5.9.3)':
+ dependencies:
+ '@codemirror/autocomplete': 6.20.1
+ '@codemirror/commands': 6.10.3
+ '@codemirror/lang-css': 6.3.1
+ '@codemirror/lang-html': 6.4.11
+ '@codemirror/lang-json': 6.0.2
+ '@codemirror/lang-xml': 6.1.0
+ '@codemirror/lang-yaml': 6.1.3
+ '@codemirror/language': 6.12.3
+ '@codemirror/lint': 6.9.5
+ '@codemirror/state': 6.6.0
+ '@codemirror/view': 6.41.1
+ '@lezer/common': 1.5.2
+ '@lezer/highlight': 1.2.3
+ '@replit/codemirror-css-color-picker': 6.3.0(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.41.1)
+ vue: 3.5.33(typescript@5.9.3)
+ transitivePeerDependencies:
+ - typescript
+
+ '@scalar/use-hooks@0.4.3(typescript@5.9.3)':
+ dependencies:
+ '@scalar/use-toasts': 0.10.2(typescript@5.9.3)
+ '@vueuse/core': 13.9.0(vue@3.5.33(typescript@5.9.3))
+ cva: 1.0.0-beta.4(typescript@5.9.3)
+ tailwind-merge: 3.5.0
+ vue: 3.5.33(typescript@5.9.3)
+ zod: 4.4.3
+ transitivePeerDependencies:
+ - typescript
+
+ '@scalar/use-toasts@0.10.2(typescript@5.9.3)':
+ dependencies:
+ vue: 3.5.33(typescript@5.9.3)
+ vue-sonner: 1.3.2
+ transitivePeerDependencies:
+ - typescript
+
+ '@scalar/validation@0.3.2': {}
+
+ '@scalar/workspace-store@0.49.2(typescript@5.9.3)':
+ dependencies:
+ '@scalar/helpers': 0.6.0
+ '@scalar/json-magic': 0.12.12
+ '@scalar/openapi-upgrader': 0.2.7
+ '@scalar/snippetz': 0.9.6
+ '@scalar/typebox': 0.1.3
+ '@scalar/types': 0.9.6
+ '@scalar/validation': 0.3.2
+ js-base64: 3.7.8
+ type-fest: 5.6.0
+ vue: 3.5.33(typescript@5.9.3)
+ yaml: 2.8.4
+ transitivePeerDependencies:
+ - typescript
+
+ '@standard-schema/spec@1.1.0': {}
+
+ '@swc/helpers@0.5.21':
+ dependencies:
+ tslib: 2.8.1
+
+ '@tailwindcss/node@4.2.4':
+ dependencies:
+ '@jridgewell/remapping': 2.3.5
+ enhanced-resolve: 5.21.2
+ jiti: 2.7.0
+ lightningcss: 1.32.0
+ magic-string: 0.30.21
+ source-map-js: 1.2.1
+ tailwindcss: 4.2.4
+
+ '@tailwindcss/oxide-android-arm64@4.2.4':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-arm64@4.2.4':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-x64@4.2.4':
+ optional: true
+
+ '@tailwindcss/oxide-freebsd-x64@4.2.4':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.4':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.2.4':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.2.4':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.2.4':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-musl@4.2.4':
+ optional: true
+
+ '@tailwindcss/oxide-wasm32-wasi@4.2.4':
+ optional: true
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.2.4':
+ optional: true
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.2.4':
+ optional: true
+
+ '@tailwindcss/oxide@4.2.4':
+ optionalDependencies:
+ '@tailwindcss/oxide-android-arm64': 4.2.4
+ '@tailwindcss/oxide-darwin-arm64': 4.2.4
+ '@tailwindcss/oxide-darwin-x64': 4.2.4
+ '@tailwindcss/oxide-freebsd-x64': 4.2.4
+ '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.4
+ '@tailwindcss/oxide-linux-arm64-gnu': 4.2.4
+ '@tailwindcss/oxide-linux-arm64-musl': 4.2.4
+ '@tailwindcss/oxide-linux-x64-gnu': 4.2.4
+ '@tailwindcss/oxide-linux-x64-musl': 4.2.4
+ '@tailwindcss/oxide-wasm32-wasi': 4.2.4
+ '@tailwindcss/oxide-win32-arm64-msvc': 4.2.4
+ '@tailwindcss/oxide-win32-x64-msvc': 4.2.4
+
+ '@tailwindcss/vite@4.2.4(vite@7.3.3(@types/node@24.12.3)(jiti@2.7.0)(lightningcss@1.32.0)(yaml@2.8.4))':
+ dependencies:
+ '@tailwindcss/node': 4.2.4
+ '@tailwindcss/oxide': 4.2.4
+ tailwindcss: 4.2.4
+ vite: 7.3.3(@types/node@24.12.3)(jiti@2.7.0)(lightningcss@1.32.0)(yaml@2.8.4)
+
+ '@tanstack/query-core@5.100.9': {}
+
+ '@tanstack/react-query@5.100.9(react@19.2.6)':
+ dependencies:
+ '@tanstack/query-core': 5.100.9
+ react: 19.2.6
+
+ '@tanstack/virtual-core@3.14.0': {}
+
+ '@tanstack/vue-virtual@3.13.24(vue@3.5.33(typescript@5.9.3))':
+ dependencies:
+ '@tanstack/virtual-core': 3.14.0
+ vue: 3.5.33(typescript@5.9.3)
+
+ '@types/babel__core@7.20.5':
+ dependencies:
+ '@babel/parser': 7.29.3
+ '@babel/types': 7.29.0
+ '@types/babel__generator': 7.27.0
+ '@types/babel__template': 7.4.4
+ '@types/babel__traverse': 7.28.0
+
+ '@types/babel__generator@7.27.0':
+ dependencies:
+ '@babel/types': 7.29.0
+
+ '@types/babel__template@7.4.4':
+ dependencies:
+ '@babel/parser': 7.29.3
+ '@babel/types': 7.29.0
+
+ '@types/babel__traverse@7.28.0':
+ dependencies:
+ '@babel/types': 7.29.0
+
+ '@types/debug@4.1.13':
+ dependencies:
+ '@types/ms': 2.1.0
+
+ '@types/estree@1.0.8': {}
+
+ '@types/har-format@1.2.16': {}
+
+ '@types/hast@3.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/mdast@4.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/ms@2.1.0': {}
+
+ '@types/node@24.12.3':
+ dependencies:
+ undici-types: 7.16.0
+
+ '@types/react-dom@19.2.3(@types/react@19.2.14)':
+ dependencies:
+ '@types/react': 19.2.14
+
+ '@types/react@19.2.14':
+ dependencies:
+ csstype: 3.2.3
+
+ '@types/trusted-types@2.0.7':
+ optional: true
+
+ '@types/unist@3.0.3': {}
+
+ '@types/web-bluetooth@0.0.20': {}
+
+ '@types/web-bluetooth@0.0.21': {}
+
+ '@ungap/structured-clone@1.3.1': {}
+
+ '@unhead/vue@2.1.13(vue@3.5.33(typescript@5.9.3))':
+ dependencies:
+ hookable: 6.1.1
+ unhead: 2.1.13
+ vue: 3.5.33(typescript@5.9.3)
+
+ '@vercel/oidc@3.1.0': {}
+
+ '@vitejs/plugin-react@5.2.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.7.0)(lightningcss@1.32.0)(yaml@2.8.4))':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0)
+ '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0)
+ '@rolldown/pluginutils': 1.0.0-rc.3
+ '@types/babel__core': 7.20.5
+ react-refresh: 0.18.0
+ vite: 7.3.3(@types/node@24.12.3)(jiti@2.7.0)(lightningcss@1.32.0)(yaml@2.8.4)
+ transitivePeerDependencies:
+ - supports-color
+
+ '@vue-macros/common@3.1.2(vue@3.5.33(typescript@5.9.3))':
+ dependencies:
+ '@vue/compiler-sfc': 3.5.33
+ ast-kit: 2.2.0
+ local-pkg: 1.1.2
+ magic-string-ast: 1.0.3
+ unplugin-utils: 0.3.1
+ optionalDependencies:
+ vue: 3.5.33(typescript@5.9.3)
+
+ '@vue/compiler-core@3.5.33':
+ dependencies:
+ '@babel/parser': 7.29.3
+ '@vue/shared': 3.5.33
+ entities: 7.0.1
+ estree-walker: 2.0.2
+ source-map-js: 1.2.1
+
+ '@vue/compiler-dom@3.5.33':
+ dependencies:
+ '@vue/compiler-core': 3.5.33
+ '@vue/shared': 3.5.33
+
+ '@vue/compiler-sfc@3.5.33':
+ dependencies:
+ '@babel/parser': 7.29.3
+ '@vue/compiler-core': 3.5.33
+ '@vue/compiler-dom': 3.5.33
+ '@vue/compiler-ssr': 3.5.33
+ '@vue/shared': 3.5.33
+ estree-walker: 2.0.2
+ magic-string: 0.30.21
+ postcss: 8.5.14
+ source-map-js: 1.2.1
+
+ '@vue/compiler-ssr@3.5.33':
+ dependencies:
+ '@vue/compiler-dom': 3.5.33
+ '@vue/shared': 3.5.33
+
+ '@vue/devtools-api@8.1.1':
+ dependencies:
+ '@vue/devtools-kit': 8.1.1
+
+ '@vue/devtools-kit@8.1.1':
+ dependencies:
+ '@vue/devtools-shared': 8.1.1
+ birpc: 2.9.0
+ hookable: 5.5.3
+ perfect-debounce: 2.1.0
+
+ '@vue/devtools-shared@8.1.1': {}
+
+ '@vue/reactivity@3.5.33':
+ dependencies:
+ '@vue/shared': 3.5.33
+
+ '@vue/runtime-core@3.5.33':
+ dependencies:
+ '@vue/reactivity': 3.5.33
+ '@vue/shared': 3.5.33
+
+ '@vue/runtime-dom@3.5.33':
+ dependencies:
+ '@vue/reactivity': 3.5.33
+ '@vue/runtime-core': 3.5.33
+ '@vue/shared': 3.5.33
+ csstype: 3.2.3
+
+ '@vue/server-renderer@3.5.33(vue@3.5.33(typescript@5.9.3))':
+ dependencies:
+ '@vue/compiler-ssr': 3.5.33
+ '@vue/shared': 3.5.33
+ vue: 3.5.33(typescript@5.9.3)
+
+ '@vue/shared@3.5.33': {}
+
+ '@vueuse/core@10.11.1(vue@3.5.33(typescript@5.9.3))':
+ dependencies:
+ '@types/web-bluetooth': 0.0.20
+ '@vueuse/metadata': 10.11.1
+ '@vueuse/shared': 10.11.1(vue@3.5.33(typescript@5.9.3))
+ vue-demi: 0.14.10(vue@3.5.33(typescript@5.9.3))
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@vueuse/core@13.9.0(vue@3.5.33(typescript@5.9.3))':
+ dependencies:
+ '@types/web-bluetooth': 0.0.21
+ '@vueuse/metadata': 13.9.0
+ '@vueuse/shared': 13.9.0(vue@3.5.33(typescript@5.9.3))
+ vue: 3.5.33(typescript@5.9.3)
+
+ '@vueuse/integrations@13.9.0(focus-trap@7.8.0)(fuse.js@7.3.0)(vue@3.5.33(typescript@5.9.3))':
+ dependencies:
+ '@vueuse/core': 13.9.0(vue@3.5.33(typescript@5.9.3))
+ '@vueuse/shared': 13.9.0(vue@3.5.33(typescript@5.9.3))
+ vue: 3.5.33(typescript@5.9.3)
+ optionalDependencies:
+ focus-trap: 7.8.0
+ fuse.js: 7.3.0
+
+ '@vueuse/metadata@10.11.1': {}
+
+ '@vueuse/metadata@13.9.0': {}
+
+ '@vueuse/shared@10.11.1(vue@3.5.33(typescript@5.9.3))':
+ dependencies:
+ vue-demi: 0.14.10(vue@3.5.33(typescript@5.9.3))
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@vueuse/shared@13.9.0(vue@3.5.33(typescript@5.9.3))':
+ dependencies:
+ vue: 3.5.33(typescript@5.9.3)
+
+ acorn@8.16.0: {}
+
+ ai@6.0.33(zod@4.4.3):
+ dependencies:
+ '@ai-sdk/gateway': 3.0.13(zod@4.4.3)
+ '@ai-sdk/provider': 3.0.2
+ '@ai-sdk/provider-utils': 4.0.5(zod@4.4.3)
+ '@opentelemetry/api': 1.9.0
+ zod: 4.4.3
+
+ aria-hidden@1.2.6:
+ dependencies:
+ tslib: 2.8.1
+
+ ast-kit@2.2.0:
+ dependencies:
+ '@babel/parser': 7.29.3
+ pathe: 2.0.3
+
+ ast-walker-scope@0.8.3:
+ dependencies:
+ '@babel/parser': 7.29.3
+ ast-kit: 2.2.0
+
+ bail@2.0.2: {}
+
+ baseline-browser-mapping@2.10.27: {}
+
+ birpc@2.9.0: {}
+
+ browserslist@4.28.2:
+ dependencies:
+ baseline-browser-mapping: 2.10.27
+ caniuse-lite: 1.0.30001792
+ electron-to-chromium: 1.5.352
+ node-releases: 2.0.38
+ update-browserslist-db: 1.2.3(browserslist@4.28.2)
+
+ caniuse-lite@1.0.30001792: {}
+
+ ccount@2.0.1: {}
+
+ chalk@5.6.2: {}
+
+ character-entities-html4@2.1.0: {}
+
+ character-entities-legacy@3.0.0: {}
+
+ character-entities@2.0.2: {}
+
+ chokidar@5.0.0:
+ dependencies:
+ readdirp: 5.0.0
+
+ class-variance-authority@0.7.1:
+ dependencies:
+ clsx: 2.1.1
+
+ clsx@2.1.1: {}
+
+ comma-separated-tokens@2.0.3: {}
+
+ confbox@0.1.8: {}
+
+ confbox@0.2.4: {}
+
+ convert-hrtime@5.0.0: {}
+
+ convert-source-map@2.0.0: {}
+
+ cookie@1.1.1: {}
+
+ crelt@1.0.6: {}
+
+ csstype@3.2.3: {}
+
+ cva@1.0.0-beta.4(typescript@5.9.3):
+ dependencies:
+ clsx: 2.1.1
+ optionalDependencies:
+ typescript: 5.9.3
+
+ debug@4.4.3:
+ dependencies:
+ ms: 2.1.3
+
+ decode-named-character-reference@1.3.0:
+ dependencies:
+ character-entities: 2.0.2
+
+ defu@6.1.7: {}
+
+ dequal@2.0.3: {}
+
+ detect-libc@2.1.2: {}
+
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
+
+ dompurify@3.2.7:
+ optionalDependencies:
+ '@types/trusted-types': 2.0.7
+
+ electron-to-chromium@1.5.352: {}
+
+ enhanced-resolve@5.21.2:
+ dependencies:
+ graceful-fs: 4.2.11
+ tapable: 2.3.3
+
+ entities@6.0.1: {}
+
+ entities@7.0.1: {}
+
+ esbuild@0.27.7:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.27.7
+ '@esbuild/android-arm': 0.27.7
+ '@esbuild/android-arm64': 0.27.7
+ '@esbuild/android-x64': 0.27.7
+ '@esbuild/darwin-arm64': 0.27.7
+ '@esbuild/darwin-x64': 0.27.7
+ '@esbuild/freebsd-arm64': 0.27.7
+ '@esbuild/freebsd-x64': 0.27.7
+ '@esbuild/linux-arm': 0.27.7
+ '@esbuild/linux-arm64': 0.27.7
+ '@esbuild/linux-ia32': 0.27.7
+ '@esbuild/linux-loong64': 0.27.7
+ '@esbuild/linux-mips64el': 0.27.7
+ '@esbuild/linux-ppc64': 0.27.7
+ '@esbuild/linux-riscv64': 0.27.7
+ '@esbuild/linux-s390x': 0.27.7
+ '@esbuild/linux-x64': 0.27.7
+ '@esbuild/netbsd-arm64': 0.27.7
+ '@esbuild/netbsd-x64': 0.27.7
+ '@esbuild/openbsd-arm64': 0.27.7
+ '@esbuild/openbsd-x64': 0.27.7
+ '@esbuild/openharmony-arm64': 0.27.7
+ '@esbuild/sunos-x64': 0.27.7
+ '@esbuild/win32-arm64': 0.27.7
+ '@esbuild/win32-ia32': 0.27.7
+ '@esbuild/win32-x64': 0.27.7
+
+ escalade@3.2.0: {}
+
+ escape-string-regexp@5.0.0: {}
+
+ estree-walker@2.0.2: {}
+
+ eventsource-parser@3.0.8: {}
+
+ exsolve@1.0.8: {}
+
+ extend@3.0.2: {}
+
+ fast-deep-equal@3.1.3: {}
+
+ fdir@6.5.0(picomatch@4.0.4):
+ optionalDependencies:
+ picomatch: 4.0.4
+
+ flatted@3.4.2: {}
+
+ focus-trap@7.8.0:
+ dependencies:
+ tabbable: 6.4.0
+
+ fsevents@2.3.3:
+ optional: true
+
+ function-timeout@1.0.2: {}
+
+ fuse.js@7.3.0: {}
+
+ gensync@1.0.0-beta.2: {}
+
+ get-own-enumerable-keys@1.0.0: {}
+
+ graceful-fs@4.2.11: {}
+
+ guess-json-indent@3.0.1: {}
+
+ hast-util-embedded@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-is-element: 3.0.0
+
+ hast-util-format@1.1.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-embedded: 3.0.0
+ hast-util-minify-whitespace: 1.0.1
+ hast-util-phrasing: 3.0.1
+ hast-util-whitespace: 3.0.0
+ html-whitespace-sensitive-tag-names: 3.0.1
+ unist-util-visit-parents: 6.0.2
+
+ hast-util-from-html@2.0.3:
+ dependencies:
+ '@types/hast': 3.0.4
+ devlop: 1.1.0
+ hast-util-from-parse5: 8.0.3
+ parse5: 7.3.0
+ vfile: 6.0.3
+ vfile-message: 4.0.3
+
+ hast-util-from-parse5@8.0.3:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ devlop: 1.1.0
+ hastscript: 9.0.1
+ property-information: 7.1.0
+ vfile: 6.0.3
+ vfile-location: 5.0.3
+ web-namespaces: 2.0.1
+
+ hast-util-has-property@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-is-body-ok-link@3.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-is-element@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-minify-whitespace@1.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-embedded: 3.0.0
+ hast-util-is-element: 3.0.0
+ hast-util-whitespace: 3.0.0
+ unist-util-is: 6.0.1
+
+ hast-util-parse-selector@4.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-phrasing@3.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-embedded: 3.0.0
+ hast-util-has-property: 3.0.0
+ hast-util-is-body-ok-link: 3.0.1
+ hast-util-is-element: 3.0.0
+
+ hast-util-raw@9.1.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ '@ungap/structured-clone': 1.3.1
+ hast-util-from-parse5: 8.0.3
+ hast-util-to-parse5: 8.0.1
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.1
+ parse5: 7.3.0
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.1.0
+ vfile: 6.0.3
+ web-namespaces: 2.0.1
+ zwitch: 2.0.4
+
+ hast-util-sanitize@5.0.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@ungap/structured-clone': 1.3.1
+ unist-util-position: 5.0.0
+
+ hast-util-to-html@9.0.5:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ comma-separated-tokens: 2.0.3
+ hast-util-whitespace: 3.0.0
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.1
+ property-information: 7.1.0
+ space-separated-tokens: 2.0.2
+ stringify-entities: 4.0.4
+ zwitch: 2.0.4
+
+ hast-util-to-parse5@8.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ property-information: 7.1.0
+ space-separated-tokens: 2.0.2
+ web-namespaces: 2.0.1
+ zwitch: 2.0.4
+
+ hast-util-to-text@4.0.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ hast-util-is-element: 3.0.0
+ unist-util-find-after: 5.0.0
+
+ hast-util-whitespace@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hastscript@9.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ comma-separated-tokens: 2.0.3
+ hast-util-parse-selector: 4.0.0
+ property-information: 7.1.0
+ space-separated-tokens: 2.0.2
+
+ highlight.js@11.11.1: {}
+
+ hookable@5.5.3: {}
+
+ hookable@6.1.1: {}
+
+ html-void-elements@3.0.0: {}
+
+ html-whitespace-sensitive-tag-names@3.0.1: {}
+
+ identifier-regex@1.0.1:
+ dependencies:
+ reserved-identifiers: 1.2.0
+
+ is-absolute-url@4.0.1: {}
+
+ is-identifier@1.0.1:
+ dependencies:
+ identifier-regex: 1.0.1
+ super-regex: 1.1.0
+
+ is-obj@3.0.0: {}
+
+ is-plain-obj@4.1.0: {}
+
+ is-regexp@3.1.0: {}
+
+ jiti@2.7.0: {}
+
+ js-base64@3.7.8: {}
+
+ js-tokens@4.0.0: {}
+
+ jsesc@3.1.0: {}
+
+ json-schema@0.4.0: {}
+
+ json5@2.2.3: {}
+
+ jsonc-parser@3.3.1: {}
+
+ lightningcss-android-arm64@1.32.0:
+ optional: true
+
+ lightningcss-darwin-arm64@1.32.0:
+ optional: true
+
+ lightningcss-darwin-x64@1.32.0:
+ optional: true
+
+ lightningcss-freebsd-x64@1.32.0:
+ optional: true
+
+ lightningcss-linux-arm-gnueabihf@1.32.0:
+ optional: true
+
+ lightningcss-linux-arm64-gnu@1.32.0:
+ optional: true
+
+ lightningcss-linux-arm64-musl@1.32.0:
+ optional: true
+
+ lightningcss-linux-x64-gnu@1.32.0:
+ optional: true
+
+ lightningcss-linux-x64-musl@1.32.0:
+ optional: true
+
+ lightningcss-win32-arm64-msvc@1.32.0:
+ optional: true
+
+ lightningcss-win32-x64-msvc@1.32.0:
+ optional: true
+
+ lightningcss@1.32.0:
+ dependencies:
+ detect-libc: 2.1.2
+ optionalDependencies:
+ lightningcss-android-arm64: 1.32.0
+ lightningcss-darwin-arm64: 1.32.0
+ lightningcss-darwin-x64: 1.32.0
+ lightningcss-freebsd-x64: 1.32.0
+ lightningcss-linux-arm-gnueabihf: 1.32.0
+ lightningcss-linux-arm64-gnu: 1.32.0
+ lightningcss-linux-arm64-musl: 1.32.0
+ lightningcss-linux-x64-gnu: 1.32.0
+ lightningcss-linux-x64-musl: 1.32.0
+ lightningcss-win32-arm64-msvc: 1.32.0
+ lightningcss-win32-x64-msvc: 1.32.0
+
+ local-pkg@1.1.2:
+ dependencies:
+ mlly: 1.8.2
+ pkg-types: 2.3.1
+ quansync: 0.2.11
+
+ longest-streak@3.1.0: {}
+
+ lowlight@3.3.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ devlop: 1.1.0
+ highlight.js: 11.11.1
+
+ lru-cache@5.1.1:
+ dependencies:
+ yallist: 3.1.1
+
+ lucide-react@0.469.0(react@19.2.6):
+ dependencies:
+ react: 19.2.6
+
+ lucide-react@0.553.0(react@19.2.6):
+ dependencies:
+ react: 19.2.6
+
+ magic-string-ast@1.0.3:
+ dependencies:
+ magic-string: 0.30.21
+
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ make-asynchronous@1.1.0:
+ dependencies:
+ p-event: 6.0.1
+ type-fest: 4.41.0
+ web-worker: 1.5.0
+
+ markdown-table@3.0.4: {}
+
+ marked@14.0.0: {}
+
+ mdast-util-find-and-replace@3.0.2:
+ dependencies:
+ '@types/mdast': 4.0.4
+ escape-string-regexp: 5.0.0
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.0.2
+
+ mdast-util-from-markdown@2.0.3:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ mdast-util-to-string: 4.0.0
+ micromark: 4.0.2
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-decode-string: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ unist-util-stringify-position: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-find-and-replace: 3.0.2
+ micromark-util-character: 2.1.1
+
+ mdast-util-gfm-footnote@2.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.1.2
+ micromark-util-normalize-identifier: 2.0.1
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-strikethrough@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-table@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ markdown-table: 3.0.4
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm@3.1.0:
+ dependencies:
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-gfm-autolink-literal: 2.0.1
+ mdast-util-gfm-footnote: 2.1.0
+ mdast-util-gfm-strikethrough: 2.0.0
+ mdast-util-gfm-table: 2.0.0
+ mdast-util-gfm-task-list-item: 2.0.0
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-phrasing@4.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ unist-util-is: 6.0.1
+
+ mdast-util-to-hast@13.2.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ '@ungap/structured-clone': 1.3.1
+ devlop: 1.1.0
+ micromark-util-sanitize-uri: 2.0.1
+ trim-lines: 3.0.1
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.1.0
+ vfile: 6.0.3
+
+ mdast-util-to-markdown@2.1.2:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ longest-streak: 3.1.0
+ mdast-util-phrasing: 4.1.0
+ mdast-util-to-string: 4.0.0
+ micromark-util-classify-character: 2.0.1
+ micromark-util-decode-string: 2.0.1
+ unist-util-visit: 5.1.0
+ zwitch: 2.0.4
+
+ mdast-util-to-string@4.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+
+ microdiff@1.5.0: {}
+
+ micromark-core-commonmark@2.0.3:
+ dependencies:
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ micromark-factory-destination: 2.0.1
+ micromark-factory-label: 2.0.1
+ micromark-factory-space: 2.0.1
+ micromark-factory-title: 2.0.1
+ micromark-factory-whitespace: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-html-tag-name: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-footnote@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.3
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-table@2.1.1:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ dependencies:
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm@3.0.0:
+ dependencies:
+ micromark-extension-gfm-autolink-literal: 2.1.0
+ micromark-extension-gfm-footnote: 2.1.0
+ micromark-extension-gfm-strikethrough: 2.1.0
+ micromark-extension-gfm-table: 2.1.1
+ micromark-extension-gfm-tagfilter: 2.0.0
+ micromark-extension-gfm-task-list-item: 2.1.0
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-destination@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-label@2.0.1:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-space@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-title@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-whitespace@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-character@2.1.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-chunked@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-classify-character@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-combine-extensions@2.0.1:
+ dependencies:
+ micromark-util-chunked: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-decode-string@2.0.1:
+ dependencies:
+ decode-named-character-reference: 1.3.0
+ micromark-util-character: 2.1.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-encode@2.0.1: {}
+
+ micromark-util-html-tag-name@2.0.1: {}
+
+ micromark-util-normalize-identifier@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-resolve-all@2.0.1:
+ dependencies:
+ micromark-util-types: 2.0.2
+
+ micromark-util-sanitize-uri@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-encode: 2.0.1
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-subtokenize@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-symbol@2.0.1: {}
+
+ micromark-util-types@2.0.2: {}
+
+ micromark@4.0.2:
+ dependencies:
+ '@types/debug': 4.1.13
+ debug: 4.4.3
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.3
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-encode: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mlly@1.8.2:
+ dependencies:
+ acorn: 8.16.0
+ pathe: 2.0.3
+ pkg-types: 1.3.1
+ ufo: 1.6.4
+
+ monaco-editor@0.55.1:
+ dependencies:
+ dompurify: 3.2.7
+ marked: 14.0.0
+
+ monaco-languageserver-types@0.4.0:
+ dependencies:
+ monaco-types: 0.1.2
+ vscode-languageserver-protocol: 3.17.5
+ vscode-uri: 3.1.0
+
+ monaco-marker-data-provider@1.2.5:
+ dependencies:
+ monaco-types: 0.1.2
+
+ monaco-types@0.1.2: {}
+
+ monaco-worker-manager@2.0.1(monaco-editor@0.55.1):
+ dependencies:
+ monaco-editor: 0.55.1
+
+ monaco-yaml@5.4.1(monaco-editor@0.55.1):
+ dependencies:
+ jsonc-parser: 3.3.1
+ monaco-editor: 0.55.1
+ monaco-languageserver-types: 0.4.0
+ monaco-marker-data-provider: 1.2.5
+ monaco-types: 0.1.2
+ monaco-worker-manager: 2.0.1(monaco-editor@0.55.1)
+ path-browserify: 1.0.1
+ prettier: 3.8.3
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-languageserver-types: 3.17.5
+ vscode-uri: 3.1.0
+ yaml: 2.8.4
+
+ ms@2.1.3: {}
+
+ muggle-string@0.4.1: {}
+
+ nanoid@3.3.12: {}
+
+ nanoid@5.1.11: {}
+
+ neverpanic@0.0.7(typescript@5.9.3):
+ dependencies:
+ typescript: 5.9.3
+
+ node-releases@2.0.38: {}
+
+ p-event@6.0.1:
+ dependencies:
+ p-timeout: 6.1.4
+
+ p-timeout@6.1.4: {}
+
+ parse-ms@4.0.0: {}
+
+ parse5@7.3.0:
+ dependencies:
+ entities: 6.0.1
+
+ path-browserify@1.0.1: {}
+
+ pathe@2.0.3: {}
+
+ perfect-debounce@2.1.0: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@4.0.4: {}
+
+ pkg-types@1.3.1:
+ dependencies:
+ confbox: 0.1.8
+ mlly: 1.8.2
+ pathe: 2.0.3
+
+ pkg-types@2.3.1:
+ dependencies:
+ confbox: 0.2.4
+ exsolve: 1.0.8
+ pathe: 2.0.3
+
+ postcss@8.5.14:
+ dependencies:
+ nanoid: 3.3.12
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ prettier@3.8.3: {}
+
+ pretty-ms@9.3.0:
+ dependencies:
+ parse-ms: 4.0.0
+
+ property-information@7.1.0: {}
+
+ quansync@0.2.11: {}
+
+ radix-vue@1.9.17(vue@3.5.33(typescript@5.9.3)):
+ dependencies:
+ '@floating-ui/dom': 1.7.6
+ '@floating-ui/vue': 1.1.11(vue@3.5.33(typescript@5.9.3))
+ '@internationalized/date': 3.12.1
+ '@internationalized/number': 3.6.6
+ '@tanstack/vue-virtual': 3.13.24(vue@3.5.33(typescript@5.9.3))
+ '@vueuse/core': 10.11.1(vue@3.5.33(typescript@5.9.3))
+ '@vueuse/shared': 10.11.1(vue@3.5.33(typescript@5.9.3))
+ aria-hidden: 1.2.6
+ defu: 6.1.7
+ fast-deep-equal: 3.1.3
+ nanoid: 5.1.11
+ vue: 3.5.33(typescript@5.9.3)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+
+ react-dom@19.2.6(react@19.2.6):
+ dependencies:
+ react: 19.2.6
+ scheduler: 0.27.0
+
+ react-refresh@0.18.0: {}
+
+ react@19.2.6: {}
+
+ readdirp@5.0.0: {}
+
+ rehype-external-links@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@ungap/structured-clone': 1.3.1
+ hast-util-is-element: 3.0.0
+ is-absolute-url: 4.0.1
+ space-separated-tokens: 2.0.2
+ unist-util-visit: 5.1.0
+
+ rehype-format@5.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-format: 1.1.0
+
+ rehype-parse@9.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-from-html: 2.0.3
+ unified: 11.0.5
+
+ rehype-raw@7.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-raw: 9.1.0
+ vfile: 6.0.3
+
+ rehype-sanitize@6.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-sanitize: 5.0.2
+
+ rehype-stringify@10.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-to-html: 9.0.5
+ unified: 11.0.5
+
+ remark-gfm@4.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-gfm: 3.1.0
+ micromark-extension-gfm: 3.0.0
+ remark-parse: 11.0.0
+ remark-stringify: 11.0.0
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-parse@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.0.3
+ micromark-util-types: 2.0.2
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-rehype@11.1.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ mdast-util-to-hast: 13.2.1
+ unified: 11.0.5
+ vfile: 6.0.3
+
+ remark-stringify@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-to-markdown: 2.1.2
+ unified: 11.0.5
+
+ reserved-identifiers@1.2.0: {}
+
+ rollup@4.60.3:
+ dependencies:
+ '@types/estree': 1.0.8
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.60.3
+ '@rollup/rollup-android-arm64': 4.60.3
+ '@rollup/rollup-darwin-arm64': 4.60.3
+ '@rollup/rollup-darwin-x64': 4.60.3
+ '@rollup/rollup-freebsd-arm64': 4.60.3
+ '@rollup/rollup-freebsd-x64': 4.60.3
+ '@rollup/rollup-linux-arm-gnueabihf': 4.60.3
+ '@rollup/rollup-linux-arm-musleabihf': 4.60.3
+ '@rollup/rollup-linux-arm64-gnu': 4.60.3
+ '@rollup/rollup-linux-arm64-musl': 4.60.3
+ '@rollup/rollup-linux-loong64-gnu': 4.60.3
+ '@rollup/rollup-linux-loong64-musl': 4.60.3
+ '@rollup/rollup-linux-ppc64-gnu': 4.60.3
+ '@rollup/rollup-linux-ppc64-musl': 4.60.3
+ '@rollup/rollup-linux-riscv64-gnu': 4.60.3
+ '@rollup/rollup-linux-riscv64-musl': 4.60.3
+ '@rollup/rollup-linux-s390x-gnu': 4.60.3
+ '@rollup/rollup-linux-x64-gnu': 4.60.3
+ '@rollup/rollup-linux-x64-musl': 4.60.3
+ '@rollup/rollup-openbsd-x64': 4.60.3
+ '@rollup/rollup-openharmony-arm64': 4.60.3
+ '@rollup/rollup-win32-arm64-msvc': 4.60.3
+ '@rollup/rollup-win32-ia32-msvc': 4.60.3
+ '@rollup/rollup-win32-x64-gnu': 4.60.3
+ '@rollup/rollup-win32-x64-msvc': 4.60.3
+ fsevents: 2.3.3
+
+ scheduler@0.27.0: {}
+
+ scule@1.3.0: {}
+
+ semver@6.3.1: {}
+
+ set-cookie-parser@3.1.0: {}
+
+ shell-quote@1.8.3: {}
+
+ source-map-js@1.2.1: {}
+
+ space-separated-tokens@2.0.2: {}
+
+ string-byte-length@3.0.1: {}
+
+ string-byte-slice@3.0.1: {}
+
+ stringify-entities@4.0.4:
+ dependencies:
+ character-entities-html4: 2.1.0
+ character-entities-legacy: 3.0.0
+
+ stringify-object@6.0.0:
+ dependencies:
+ get-own-enumerable-keys: 1.0.0
+ is-identifier: 1.0.1
+ is-obj: 3.0.0
+ is-regexp: 3.1.0
+
+ style-mod@4.1.3: {}
+
+ super-regex@1.1.0:
+ dependencies:
+ function-timeout: 1.0.2
+ make-asynchronous: 1.1.0
+ time-span: 5.1.0
+
+ swrv@1.2.0(vue@3.5.33(typescript@5.9.3)):
+ dependencies:
+ vue: 3.5.33(typescript@5.9.3)
+
+ tabbable@6.4.0: {}
+
+ tagged-tag@1.0.0: {}
+
+ tailwind-merge@2.6.1: {}
+
+ tailwind-merge@3.5.0: {}
+
+ tailwindcss@4.2.4: {}
+
+ tapable@2.3.3: {}
+
+ time-span@5.1.0:
+ dependencies:
+ convert-hrtime: 5.0.0
+
+ tinyglobby@0.2.16:
+ dependencies:
+ fdir: 6.5.0(picomatch@4.0.4)
+ picomatch: 4.0.4
+
+ trim-lines@3.0.1: {}
+
+ trough@2.2.0: {}
+
+ truncate-json@3.0.1:
+ dependencies:
+ guess-json-indent: 3.0.1
+ string-byte-length: 3.0.1
+ string-byte-slice: 3.0.1
+
+ tslib@2.8.1: {}
+
+ type-fest@4.41.0: {}
+
+ type-fest@5.6.0:
+ dependencies:
+ tagged-tag: 1.0.0
+
+ typescript@5.9.3: {}
+
+ ufo@1.6.4: {}
+
+ undici-types@7.16.0: {}
+
+ unhead@2.1.13:
+ dependencies:
+ hookable: 6.1.1
+
+ unified@11.0.5:
+ dependencies:
+ '@types/unist': 3.0.3
+ bail: 2.0.2
+ devlop: 1.1.0
+ extend: 3.0.2
+ is-plain-obj: 4.1.0
+ trough: 2.2.0
+ vfile: 6.0.3
+
+ unist-util-find-after@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+
+ unist-util-is@6.0.1:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-stringify-position@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-parents@6.0.2:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+
+ unist-util-visit@5.1.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.0.2
+
+ unplugin-utils@0.3.1:
+ dependencies:
+ pathe: 2.0.3
+ picomatch: 4.0.4
+
+ unplugin@3.0.0:
+ dependencies:
+ '@jridgewell/remapping': 2.3.5
+ picomatch: 4.0.4
+ webpack-virtual-modules: 0.6.2
+
+ update-browserslist-db@1.2.3(browserslist@4.28.2):
+ dependencies:
+ browserslist: 4.28.2
+ escalade: 3.2.0
+ picocolors: 1.1.1
+
+ vfile-location@5.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile: 6.0.3
+
+ vfile-message@4.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-stringify-position: 4.0.0
+
+ vfile@6.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile-message: 4.0.3
+
+ vite-plugin-monaco-editor@1.1.0(monaco-editor@0.55.1):
+ dependencies:
+ monaco-editor: 0.55.1
+
+ vite@7.3.3(@types/node@24.12.3)(jiti@2.7.0)(lightningcss@1.32.0)(yaml@2.8.4):
+ dependencies:
+ esbuild: 0.27.7
+ fdir: 6.5.0(picomatch@4.0.4)
+ picomatch: 4.0.4
+ postcss: 8.5.14
+ rollup: 4.60.3
+ tinyglobby: 0.2.16
+ optionalDependencies:
+ '@types/node': 24.12.3
+ fsevents: 2.3.3
+ jiti: 2.7.0
+ lightningcss: 1.32.0
+ yaml: 2.8.4
+
+ vscode-jsonrpc@8.2.0: {}
+
+ vscode-languageserver-protocol@3.17.5:
+ dependencies:
+ vscode-jsonrpc: 8.2.0
+ vscode-languageserver-types: 3.17.5
+
+ vscode-languageserver-textdocument@1.0.12: {}
+
+ vscode-languageserver-types@3.17.5: {}
+
+ vscode-uri@3.1.0: {}
+
+ vue-component-type-helpers@3.2.8: {}
+
+ vue-demi@0.14.10(vue@3.5.33(typescript@5.9.3)):
+ dependencies:
+ vue: 3.5.33(typescript@5.9.3)
+
+ vue-router@5.0.4(@vue/compiler-sfc@3.5.33)(vue@3.5.33(typescript@5.9.3)):
+ dependencies:
+ '@babel/generator': 7.29.1
+ '@vue-macros/common': 3.1.2(vue@3.5.33(typescript@5.9.3))
+ '@vue/devtools-api': 8.1.1
+ ast-walker-scope: 0.8.3
+ chokidar: 5.0.0
+ json5: 2.2.3
+ local-pkg: 1.1.2
+ magic-string: 0.30.21
+ mlly: 1.8.2
+ muggle-string: 0.4.1
+ pathe: 2.0.3
+ picomatch: 4.0.4
+ scule: 1.3.0
+ tinyglobby: 0.2.16
+ unplugin: 3.0.0
+ unplugin-utils: 0.3.1
+ vue: 3.5.33(typescript@5.9.3)
+ yaml: 2.8.4
+ optionalDependencies:
+ '@vue/compiler-sfc': 3.5.33
+
+ vue-sonner@1.3.2: {}
+
+ vue@3.5.33(typescript@5.9.3):
+ dependencies:
+ '@vue/compiler-dom': 3.5.33
+ '@vue/compiler-sfc': 3.5.33
+ '@vue/runtime-dom': 3.5.33
+ '@vue/server-renderer': 3.5.33(vue@3.5.33(typescript@5.9.3))
+ '@vue/shared': 3.5.33
+ optionalDependencies:
+ typescript: 5.9.3
+
+ w3c-keyname@2.2.8: {}
+
+ web-namespaces@2.0.1: {}
+
+ web-worker@1.5.0: {}
+
+ webpack-virtual-modules@0.6.2: {}
+
+ yallist@3.1.1: {}
+
+ yaml@2.8.4: {}
+
+ zod@4.4.3: {}
+
+ zwitch@2.0.4: {}
diff --git a/opensearch/ui-src/src/main.tsx b/opensearch/ui-src/src/main.tsx
new file mode 100644
index 0000000..035b08a
--- /dev/null
+++ b/opensearch/ui-src/src/main.tsx
@@ -0,0 +1,457 @@
+import React, { useEffect, useMemo, useState } from "react";
+import { createRoot } from "react-dom/client";
+import { Database, FileJson, Play, Search } from "lucide-react";
+import { Button, FilterBar, Select } from "@flanksource/clicky-ui/components";
+import { DataTable, JsonView, type DataTableColumn } from "@flanksource/clicky-ui/data";
+import { InlineError } from "@flanksource/clicky-ui/rpc";
+import "@flanksource/clicky-ui/styles.css";
+import { pluginBuildDate, pluginVersion } from "./version";
+import "./styles.css";
+
+const FIELD_CLASS = "flex min-w-40 flex-col gap-1";
+const LABEL_CLASS = "text-[11px] font-semibold text-slate-500";
+const INPUT_CLASS =
+ "h-8 w-full rounded-md border border-slate-300 bg-white px-2 text-[13px] text-slate-950 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 disabled:cursor-not-allowed disabled:opacity-50";
+
+type ProfileParam = {
+ name: string;
+ operator: string;
+ description?: string;
+ required?: boolean;
+};
+
+type TracingColumn = {
+ name: string;
+ field: string;
+ detail?: boolean;
+};
+
+type ProfileSummary = {
+ name: string;
+ format: string;
+ backend: string;
+ index: string;
+ params: ProfileParam[];
+ columns: TracingColumn[];
+ defaults: Record;
+};
+
+type Trace = {
+ timestamp?: string;
+ trace_id?: string;
+ span_id?: string;
+ parent_id?: string;
+ service_name?: string;
+ operation_name?: string;
+ status?: string;
+ duration_ms?: number;
+ cells?: Record;
+ attributes?: Record;
+ raw?: Record;
+ children?: Trace[];
+};
+
+type TraceRow = Record & {
+ _id: string;
+ _depth: number;
+ _trace: Trace;
+};
+
+type TraceResult = {
+ profile: string;
+ index: string;
+ total: number;
+ traces: Trace[];
+};
+
+type QueryPreview = {
+ profile: string;
+ request: {
+ index: string;
+ limit: number;
+ query: Record;
+ };
+};
+
+type OperationError = Error & {
+ status?: number;
+ url?: string;
+ responseBody?: string;
+};
+
+function configIDFromURL(): string {
+ return new URLSearchParams(window.location.search).get("config_id") ?? "";
+}
+
+function operationURL(op: string): string {
+ const base = window.location.pathname.replace(/\/ui\/.*$/, "");
+ const url = new URL(base + "/operations/" + op, window.location.origin);
+ const configID = configIDFromURL();
+ if (configID) url.searchParams.set("config_id", configID);
+ return url.toString();
+}
+
+async function callOp(op: string, params: Record = {}): Promise {
+ const url = operationURL(op);
+ const res = await fetch(url, {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ credentials: "same-origin",
+ body: JSON.stringify(params),
+ });
+ if (!res.ok) {
+ const responseBody = await res.text();
+ const err = new Error(responseBody || `${op} returned ${res.status}`) as OperationError;
+ err.status = res.status;
+ err.url = url;
+ err.responseBody = responseBody;
+ throw err;
+ }
+ return (await res.json()) as T;
+}
+
+function App() {
+ const [profiles, setProfiles] = useState([]);
+ const [profileName, setProfileName] = useState("");
+ const [params, setParams] = useState>({});
+ const [from, setFrom] = useState("");
+ const [to, setTo] = useState("");
+ const [limit, setLimit] = useState(100);
+ const [result, setResult] = useState(null);
+ const [preview, setPreview] = useState(null);
+ const [selected, setSelected] = useState(null);
+ const [pendingAction, setPendingAction] = useState<"preview" | "query" | null>(null);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ callOp("profiles-list")
+ .then((items) => {
+ setProfiles(items);
+ const first = items[0];
+ if (first) {
+ setProfileName(first.name);
+ setParams(defaultParams(first));
+ }
+ })
+ .catch(setError);
+ }, []);
+
+ const profile = useMemo(
+ () => profiles.find((item) => item.name === profileName),
+ [profiles, profileName],
+ );
+
+ const rows = useMemo(() => flattenTraces(result?.traces ?? []), [result]);
+ const columns = useMemo(() => buildColumns(profile?.columns ?? []), [profile?.columns]);
+ const loading = pendingAction !== null;
+
+ function selectProfile(name: string) {
+ const next = profiles.find((item) => item.name === name);
+ setProfileName(name);
+ setParams(next ? defaultParams(next) : {});
+ setResult(null);
+ setSelected(null);
+ setPreview(null);
+ }
+
+ async function runPreview() {
+ if (!profile) return;
+ setPendingAction("preview");
+ setError(null);
+ try {
+ const next = await callOp("query-preview", requestBody(profileName, params, from, to, limit));
+ setPreview(next);
+ } catch (err) {
+ setError(err);
+ } finally {
+ setPendingAction(null);
+ }
+ }
+
+ async function runQuery() {
+ if (!profile) return;
+ setPendingAction("query");
+ setError(null);
+ try {
+ const next = await callOp("trace-query", requestBody(profileName, params, from, to, limit));
+ const nextRows = flattenTraces(next.traces);
+ setResult(next);
+ setSelected(nextRows[0] ?? null);
+ setPreview(null);
+ } catch (err) {
+ setError(err);
+ } finally {
+ setPendingAction(null);
+ }
+ }
+
+ return (
+
+
+
+
+
+ }
+ trailing={
+
+
+
+
+ v{pluginVersion}
+ {pluginBuildDate ? ` ${pluginBuildDate}` : ""}
+
+
+ }
+ >
+
+
+
+
+ {profile?.params.map((param) => (
+
setParams((prev) => ({ ...prev, [param.name]: value }))}
+ />
+ ))}
+
+
+
+ {error !== null && (
+
+
+
+ )}
+
+
+
+
+
+ {result ? `${result.total} matches in ${result.index}` : preview ? "Query preview" : "Trace query"}
+
+
+ {preview ? (
+
+
+
+ ) : result ? (
+
+ data={rows}
+ columns={columns}
+ emptyMessage="No traces matched the current query."
+ autoFilter
+ showGlobalFilter
+ globalFilterPlaceholder="Search traces..."
+ getRowId={(row) => row._id}
+ onRowClick={setSelected}
+ renderExpandedRow={(row) => (
+
+
+
+ )}
+ resizableColumns
+ persistColumnWidths
+ columnResizeStorageKey={`opensearch:${profileName}:widths`}
+ hideableColumns
+ persistColumnVisibility
+ columnVisibilityStorageKey={`opensearch:${profileName}:columns`}
+ defaultDensity="compact"
+ persistDensity
+ densityStorageKey="opensearch:trace-table:density"
+ showDensityControl
+ />
+ ) : (
+
+
+
No query results yet.
+
+ )}
+
+
+
+
+
+ );
+}
+
+function TraceTextField({
+ label,
+ value,
+ placeholder,
+ onChange,
+}: {
+ label: string;
+ value: string;
+ placeholder?: string;
+ onChange: (value: string) => void;
+}) {
+ return (
+
+
+ onChange(e.target.value)} />
+
+ );
+}
+
+function TraceNumberField({
+ label,
+ value,
+ onChange,
+}: {
+ label: string;
+ value: number;
+ onChange: (value: number) => void;
+}) {
+ return (
+
+
+ onChange(Number(e.target.value) || 100)}
+ />
+
+ );
+}
+
+function buildColumns(columns: TracingColumn[]): Array> {
+ return columns
+ .filter((col) => !col.detail)
+ .map((col) => {
+ const column: DataTableColumn = {
+ key: col.name,
+ label: col.name,
+ sortable: true,
+ filterable: true,
+ grow: /operation|message|name/i.test(col.name),
+ shrink: /status|duration/i.test(col.name),
+ align: /duration|count|size|ms$/i.test(col.name) ? "right" : "left",
+ render: (value, row) => renderCell(value, col, row),
+ filterValue: (value) => (value == null ? "" : String(value)),
+ sortValue: sortValue,
+ cellClassName: cellClass(col),
+ };
+
+ if (/time|timestamp/i.test(col.name) || /time|timestamp/i.test(col.field)) {
+ column.kind = "timestamp";
+ column.timestamp = { mode: "auto" };
+ } else if (/status/i.test(col.name)) {
+ column.kind = "status";
+ column.status = { showLabel: true };
+ }
+
+ return column;
+ });
+}
+
+function defaultParams(profile: ProfileSummary): Record {
+ const out: Record = {};
+ for (const [key, value] of Object.entries(profile.defaults ?? {})) {
+ if (value != null) out[key] = String(value);
+ }
+ return out;
+}
+
+function requestBody(profile: string, params: Record, from: string, to: string, limit: number) {
+ const cleanParams: Record = {};
+ for (const [key, value] of Object.entries(params)) {
+ if (value.trim()) cleanParams[key] = value.trim();
+ }
+ return { profile, params: cleanParams, from: from.trim(), to: to.trim(), limit };
+}
+
+function flattenTraces(traces: Trace[]): TraceRow[] {
+ const out: TraceRow[] = [];
+ const walk = (trace: Trace, depth: number) => {
+ const row: TraceRow = {
+ ...(trace.cells ?? {}),
+ _id: `${trace.trace_id || "trace"}:${trace.span_id || out.length}`,
+ _depth: depth,
+ _trace: trace,
+ };
+ out.push(row);
+ for (const child of trace.children ?? []) walk(child, depth + 1);
+ };
+ for (const trace of traces) walk(trace, 0);
+ return out;
+}
+
+function renderCell(value: unknown, col: TracingColumn, row: TraceRow): React.ReactNode {
+ if (value == null) return "";
+ const text = formatValue(value);
+ const content = /operation|name/i.test(col.name) && row._depth > 0 ? `${" ".repeat(row._depth)}${text}` : text;
+ return (
+
+ {content}
+
+ );
+}
+
+function formatValue(value: unknown): string {
+ if (typeof value === "number" && Number.isFinite(value)) {
+ return value % 1 === 0 ? String(value) : value.toFixed(2);
+ }
+ if (typeof value === "object") return JSON.stringify(value);
+ return String(value);
+}
+
+function sortValue(value: unknown): unknown {
+ if (typeof value === "number") return value;
+ if (typeof value === "string") {
+ const timestamp = Date.parse(value);
+ if (Number.isFinite(timestamp) && /[-:T]/.test(value)) return timestamp;
+ const numeric = Number(value);
+ if (Number.isFinite(numeric) && value.trim() !== "") return numeric;
+ }
+ return value;
+}
+
+function cellClass(col: TracingColumn): string {
+ if (/id$/i.test(col.name) || col.name.includes("ID")) {
+ return "inline-block max-w-[360px] truncate align-bottom font-mono";
+ }
+ if (/time|duration/i.test(col.name)) return "font-mono";
+ return "inline-block max-w-[360px] truncate align-bottom";
+}
+
+createRoot(document.getElementById("root")!).render();
diff --git a/opensearch/ui-src/src/styles.css b/opensearch/ui-src/src/styles.css
new file mode 100644
index 0000000..f1d8c73
--- /dev/null
+++ b/opensearch/ui-src/src/styles.css
@@ -0,0 +1 @@
+@import "tailwindcss";
diff --git a/opensearch/ui-src/src/version.ts b/opensearch/ui-src/src/version.ts
new file mode 100644
index 0000000..edf4f9f
--- /dev/null
+++ b/opensearch/ui-src/src/version.ts
@@ -0,0 +1,2 @@
+export const pluginVersion = import.meta.env.PLUGIN_VERSION || "dev";
+export const pluginBuildDate = import.meta.env.PLUGIN_BUILD_DATE || "";
diff --git a/opensearch/ui-src/src/vite-env.d.ts b/opensearch/ui-src/src/vite-env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/opensearch/ui-src/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/opensearch/ui-src/tsconfig.json b/opensearch/ui-src/tsconfig.json
new file mode 100644
index 0000000..596336d
--- /dev/null
+++ b/opensearch/ui-src/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "useDefineForClassFields": true,
+ "lib": ["DOM", "DOM.Iterable", "ES2022"],
+ "allowJs": false,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx"
+ },
+ "include": ["src"],
+ "references": []
+}
diff --git a/opensearch/ui-src/vite.config.ts b/opensearch/ui-src/vite.config.ts
new file mode 100644
index 0000000..35ccf1a
--- /dev/null
+++ b/opensearch/ui-src/vite.config.ts
@@ -0,0 +1,12 @@
+import react from "@vitejs/plugin-react";
+import tailwindcss from "@tailwindcss/vite";
+import { defineConfig } from "vite";
+
+export default defineConfig({
+ plugins: [tailwindcss(), react()],
+ base: "./",
+ build: {
+ outDir: "../ui",
+ emptyOutDir: true
+ }
+});
diff --git a/opensearch/ui/index.html b/opensearch/ui/index.html
new file mode 100644
index 0000000..8e85153
--- /dev/null
+++ b/opensearch/ui/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+ OpenSearch
+
+
+
+
+
+
+
diff --git a/opensearch/ui_checksum.go b/opensearch/ui_checksum.go
new file mode 100644
index 0000000..a28cd5c
--- /dev/null
+++ b/opensearch/ui_checksum.go
@@ -0,0 +1,5 @@
+// Code generated by plugins/opensearch/internal/gen-checksum. DO NOT EDIT.
+
+package main
+
+const uiChecksum = "3cd62e3217a7efe783da799150f7aa62dec08278c38a3bf392631fbf81684742"