diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a1c53af..12c5fdb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: branches: [master] jobs: - build: + build-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -19,12 +19,22 @@ jobs: - name: Build run: go build ./... - - name: Test - run: go test ./... -v -race -coverprofile=coverage.txt - - name: Vet run: go vet ./... + - name: Test with coverage + run: go test ./... -race -coverprofile=coverage.out -covermode=atomic + + - name: Coverage summary + run: go tool cover -func=coverage.out + + - name: Upload coverage artifact + uses: actions/upload-artifact@v4 + with: + name: coverage + path: coverage.out + if-no-files-found: ignore + lint: runs-on: ubuntu-latest steps: @@ -34,8 +44,18 @@ jobs: with: go-version-file: go.mod - - name: Install golangci-lint - run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest + - name: gofumpt + run: | + go install mvdan.cc/gofumpt@latest + unformatted="$("$(go env GOPATH)"/bin/gofumpt -l .)" + if [ -n "$unformatted" ]; then + echo "The following files are not gofumpt-formatted:" + echo "$unformatted" + echo "Run 'make fmt' to fix." + exit 1 + fi - name: golangci-lint - run: golangci-lint run + uses: golangci/golangci-lint-action@v6 + with: + version: v2.12.2 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 5fb1efd..651b9d1 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -4,8 +4,8 @@ on: push: branches: [master] paths: - - 'docs/**' - - 'mkdocs.yml' + - 'website/**' + - '.github/workflows/docs.yml' workflow_dispatch: permissions: @@ -20,20 +20,31 @@ concurrency: jobs: build: runs-on: ubuntu-latest + defaults: + run: + working-directory: website steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: pnpm/action-setup@v4 with: - python-version: '3.12' + version: 9 - - run: pip install mkdocs-material + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: pnpm + cache-dependency-path: website/pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install --frozen-lockfile - - run: mkdocs build + - name: Build static site + run: pnpm build - uses: actions/upload-pages-artifact@v3 with: - path: site + path: website/out deploy: needs: build diff --git a/.gitignore b/.gitignore index c5d0370..a4b6f7f 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,9 @@ coverage.html Thumbs.db # Docs build -site/ +website/node_modules/ +website/.next/ +website/out/ # Config (don't commit user configs) .rc.yaml diff --git a/.golangci.yml b/.golangci.yml index 7f36b9e..7e7ff1a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,5 +1,58 @@ +# golangci-lint configuration for revenuecat-cli +# Docs: https://golangci-lint.run/usage/configuration/ +version: "2" + +run: + timeout: 5m + tests: true + linters: - disable-all: true + default: none enable: + # Core vet + correctness - govet + - staticcheck + - errcheck + - ineffassign - unused + # Bug-prone patterns + - bodyclose + - noctx + - nilerr + - errorlint + - gocritic + - prealloc + - whitespace + - misspell + - unconvert + - revive + settings: + errcheck: + check-type-assertions: true + gocritic: + disabled-checks: + - ifElseChain + - singleCaseSwitch + revive: + rules: + - name: exported + disabled: true + exclusions: + rules: + # Test files: relax some checks + - path: _test\.go + linters: + - errcheck + - bodyclose + - noctx + +formatters: + enable: + - gofumpt + - goimports + settings: + gofumpt: + extra-rules: true + goimports: + local-prefixes: + - github.com/AndroidPoet/revenuecat-cli diff --git a/Makefile b/Makefile index c40b241..56f4dc1 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # revenuecat-cli - RevenueCat CLI -# Makefile for building, testing, and releasing +# Makefile for building, testing, linting, coverage, docs, and releasing BINARY_NAME=revenuecat-cli VERSION?=$(shell git describe --tags --always --dirty 2>/dev/null || echo "dev") @@ -7,7 +7,10 @@ COMMIT?=$(shell git rev-parse --short HEAD 2>/dev/null || echo "none") DATE?=$(shell date -u +"%Y-%m-%dT%H:%M:%SZ") LDFLAGS=-ldflags "-X main.version=$(VERSION) -X main.commit=$(COMMIT) -X main.date=$(DATE)" -.PHONY: all build install clean test lint fmt deps help +COVERAGE_OUT=coverage.out +COVERAGE_HTML=coverage.html + +.PHONY: all build build-all install deps fmt fmt-check lint lint-fix test test-race cover cover-func tools docs-dev docs-build release release-snapshot clean version help all: build @@ -32,18 +35,53 @@ deps: ## Download dependencies go mod download go mod tidy -fmt: ## Format code - go fmt ./... +tools: ## Install dev tooling (gofumpt, golangci-lint) + go install mvdan.cc/gofumpt@latest + go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest + +fmt: ## Format code with gofumpt + gofumpt -w . + +fmt-check: ## Fail if any file is not gofumpt-formatted + @unformatted=$$(gofumpt -l .); \ + if [ -n "$$unformatted" ]; then \ + echo "The following files are not gofumpt-formatted:"; \ + echo "$$unformatted"; \ + echo "Run 'make fmt' to fix."; \ + exit 1; \ + fi + +lint: ## Run golangci-lint + golangci-lint run ./... + +lint-fix: ## Run golangci-lint with auto-fix + golangci-lint run --fix ./... -lint: ## Run linter - golangci-lint run +## Testing & Coverage test: ## Run tests - go test -v ./... + go test ./... + +test-race: ## Run tests with the race detector + go test ./... -race + +cover: ## Run tests with coverage and produce HTML + func reports + go test ./... -coverprofile=$(COVERAGE_OUT) -covermode=atomic + go tool cover -html=$(COVERAGE_OUT) -o $(COVERAGE_HTML) + go tool cover -func=$(COVERAGE_OUT) + @echo "HTML coverage report written to $(COVERAGE_HTML)" + +cover-func: ## Print per-function coverage to stdout + go test ./... -coverprofile=$(COVERAGE_OUT) -covermode=atomic + go tool cover -func=$(COVERAGE_OUT) + +## Docs (Nextra site under website/) + +docs-dev: ## Run the docs site locally + cd website && pnpm install && pnpm dev -test-coverage: ## Run tests with coverage - go test -v -coverprofile=coverage.out ./... - go tool cover -html=coverage.out -o coverage.html +docs-build: ## Build the static docs site + cd website && pnpm install && pnpm build ## Release @@ -58,7 +96,7 @@ release: ## Create a release (requires GITHUB_TOKEN) clean: ## Remove build artifacts rm -rf bin/ rm -rf dist/ - rm -f coverage.out coverage.html + rm -f $(COVERAGE_OUT) $(COVERAGE_HTML) version: ## Print version @echo $(VERSION) diff --git a/cmd/revenuecat-cli/commands/apps/apps.go b/cmd/revenuecat-cli/commands/apps/apps.go index 65300ef..28d016e 100644 --- a/cmd/revenuecat-cli/commands/apps/apps.go +++ b/cmd/revenuecat-cli/commands/apps/apps.go @@ -75,34 +75,34 @@ func init() { // Get flags getCmd.Flags().StringVar(&appID, "app-id", "", "app ID") - getCmd.MarkFlagRequired("app-id") - getCmd.RegisterFlagCompletionFunc("app-id", completion.AppIDs()) + _ = getCmd.MarkFlagRequired("app-id") + _ = getCmd.RegisterFlagCompletionFunc("app-id", completion.AppIDs()) // Create flags createCmd.Flags().StringVar(&appName, "name", "", "app name") createCmd.Flags().StringVar(&appType, "type", "", "app type (app_store, play_store, stripe, amazon, mac_app_store, roku, web)") createCmd.Flags().StringVar(&bundleID, "bundle-id", "", "iOS bundle ID") createCmd.Flags().StringVar(&packageName, "package-name", "", "Android package name") - createCmd.MarkFlagRequired("name") - createCmd.MarkFlagRequired("type") + _ = createCmd.MarkFlagRequired("name") + _ = createCmd.MarkFlagRequired("type") // Update flags updateCmd.Flags().StringVar(&appID, "app-id", "", "app ID") updateCmd.Flags().StringVar(&appName, "name", "", "new app name") - updateCmd.MarkFlagRequired("app-id") - updateCmd.RegisterFlagCompletionFunc("app-id", completion.AppIDs()) + _ = updateCmd.MarkFlagRequired("app-id") + _ = updateCmd.RegisterFlagCompletionFunc("app-id", completion.AppIDs()) // Delete flags var confirm bool deleteCmd.Flags().StringVar(&appID, "app-id", "", "app ID") deleteCmd.Flags().BoolVar(&confirm, "confirm", false, "confirm deletion") - deleteCmd.MarkFlagRequired("app-id") - deleteCmd.RegisterFlagCompletionFunc("app-id", completion.AppIDs()) + _ = deleteCmd.MarkFlagRequired("app-id") + _ = deleteCmd.RegisterFlagCompletionFunc("app-id", completion.AppIDs()) // API keys flags apiKeysCmd.Flags().StringVar(&appID, "app-id", "", "app ID") - apiKeysCmd.MarkFlagRequired("app-id") - apiKeysCmd.RegisterFlagCompletionFunc("app-id", completion.AppIDs()) + _ = apiKeysCmd.MarkFlagRequired("app-id") + _ = apiKeysCmd.RegisterFlagCompletionFunc("app-id", completion.AppIDs()) AppsCmd.AddCommand(listCmd) AppsCmd.AddCommand(getCmd) diff --git a/cmd/revenuecat-cli/commands/auth/auth.go b/cmd/revenuecat-cli/commands/auth/auth.go index 4d3d88a..73398d1 100644 --- a/cmd/revenuecat-cli/commands/auth/auth.go +++ b/cmd/revenuecat-cli/commands/auth/auth.go @@ -66,17 +66,17 @@ func init() { loginCmd.Flags().StringVar(&profileName, "name", "default", "profile name") loginCmd.Flags().StringVar(&apiKey, "api-key", "", "RevenueCat API v2 secret key") loginCmd.Flags().StringVar(&defaultProject, "default-project", "", "default project ID for this profile") - loginCmd.MarkFlagRequired("api-key") + _ = loginCmd.MarkFlagRequired("api-key") // Switch flags switchCmd.Flags().StringVar(&profileName, "name", "", "profile name to switch to") - switchCmd.MarkFlagRequired("name") + _ = switchCmd.MarkFlagRequired("name") // Delete flags var confirm bool deleteCmd.Flags().StringVar(&profileName, "name", "", "profile name to delete") deleteCmd.Flags().BoolVar(&confirm, "confirm", false, "confirm deletion") - deleteCmd.MarkFlagRequired("name") + _ = deleteCmd.MarkFlagRequired("name") AuthCmd.AddCommand(loginCmd) AuthCmd.AddCommand(switchCmd) diff --git a/cmd/revenuecat-cli/commands/charts/charts.go b/cmd/revenuecat-cli/commands/charts/charts.go index 3b7d39e..7350721 100644 --- a/cmd/revenuecat-cli/commands/charts/charts.go +++ b/cmd/revenuecat-cli/commands/charts/charts.go @@ -2,6 +2,7 @@ package charts import ( "bytes" + "context" "encoding/csv" "encoding/json" "fmt" @@ -15,6 +16,8 @@ import ( "time" "github.com/spf13/cobra" + "golang.org/x/text/cases" + "golang.org/x/text/language" "gopkg.in/yaml.v3" "github.com/AndroidPoet/revenuecat-cli/internal/api" @@ -22,6 +25,9 @@ import ( "github.com/AndroidPoet/revenuecat-cli/internal/output" ) +// titleCaser title-cases summary labels (replacement for the deprecated strings.Title). +var titleCaser = cases.Title(language.English) + func parseTimeout() time.Duration { t := cli.GetTimeout() d, err := time.ParseDuration(t) @@ -67,25 +73,25 @@ var chartCatalog = []chartInfo{ // --- API response types --- type ChartData struct { - Object string `json:"object"` - Category string `json:"category"` - DisplayType string `json:"display_type"` - DisplayName string `json:"display_name"` - Description string `json:"description"` - DocLink *string `json:"documentation_link,omitempty"` - LastComputedAt *int64 `json:"last_computed_at,omitempty"` - StartDate *int64 `json:"start_date,omitempty"` - EndDate *int64 `json:"end_date,omitempty"` - YAxisCurrency string `json:"yaxis_currency,omitempty"` - FilterAllowed bool `json:"filtering_allowed"` - SegmentAllowed bool `json:"segmenting_allowed"` - Resolution string `json:"resolution"` - Values json.RawMessage `json:"values"` - Summary json.RawMessage `json:"summary,omitempty"` - YAxis string `json:"yaxis"` - Segments json.RawMessage `json:"segments,omitempty"` - Measures json.RawMessage `json:"measures,omitempty"` - UserSelectors json.RawMessage `json:"user_selectors,omitempty"` + Object string `json:"object"` + Category string `json:"category"` + DisplayType string `json:"display_type"` + DisplayName string `json:"display_name"` + Description string `json:"description"` + DocLink *string `json:"documentation_link,omitempty"` + LastComputedAt *int64 `json:"last_computed_at,omitempty"` + StartDate *int64 `json:"start_date,omitempty"` + EndDate *int64 `json:"end_date,omitempty"` + YAxisCurrency string `json:"yaxis_currency,omitempty"` + FilterAllowed bool `json:"filtering_allowed"` + SegmentAllowed bool `json:"segmenting_allowed"` + Resolution string `json:"resolution"` + Values json.RawMessage `json:"values"` + Summary json.RawMessage `json:"summary,omitempty"` + YAxis string `json:"yaxis"` + Segments json.RawMessage `json:"segments,omitempty"` + Measures json.RawMessage `json:"measures,omitempty"` + UserSelectors json.RawMessage `json:"user_selectors,omitempty"` } type ChartOptions struct { @@ -103,14 +109,14 @@ type ResolutionOption struct { type SegmentOption struct { ID string `json:"id"` DisplayName string `json:"display_name"` - GroupDisplayName string `json:"group_display_name,omitempty"` + GroupDisplayName string `json:"group_display_name,omitempty"` } type FilterOption struct { - ID string `json:"id"` - DisplayName string `json:"display_name"` - GroupDisplayName string `json:"group_display_name,omitempty"` - Options []FilterValue `json:"options"` + ID string `json:"id"` + DisplayName string `json:"display_name"` + GroupDisplayName string `json:"group_display_name,omitempty"` + Options []FilterValue `json:"options"` } type FilterValue struct { @@ -223,8 +229,7 @@ func init() { // --- List --- func runList(_ *cobra.Command, _ []string) error { - output.Print(chartCatalog) - return nil + return output.Print(chartCatalog) } // --- Get --- @@ -249,8 +254,7 @@ func runGet(cmd *cobra.Command, args []string) error { return fmt.Errorf("fetching chart %s: %w", chartName, err) } - output.Print(result) - return nil + return output.Print(result) } // --- Options --- @@ -279,8 +283,7 @@ func runOptions(cmd *cobra.Command, args []string) error { return fmt.Errorf("fetching options for %s: %w", chartName, err) } - output.Print(result) - return nil + return output.Print(result) } // --- Export --- @@ -352,13 +355,13 @@ func runExport(cmd *cobra.Command, _ []string) error { ec.EndDate = time.Unix(*data.EndDate, 0).UTC().Format("2006-01-02") } - // Parse values for YAML (so it's not raw JSON) + // Parse values for YAML (so it's not raw JSON); best-effort. var vals interface{} - json.Unmarshal(data.Values, &vals) + _ = json.Unmarshal(data.Values, &vals) ec.ValuesYAML = vals var summ interface{} - json.Unmarshal(data.Summary, &summ) + _ = json.Unmarshal(data.Summary, &summ) ec.SummaryYAML = summ charts = append(charts, ec) @@ -399,7 +402,7 @@ func runExport(cmd *cobra.Command, _ []string) error { if err != nil { return fmt.Errorf("marshaling JSON: %w", err) } - if err := os.WriteFile(outFile, data, 0644); err != nil { + if err := os.WriteFile(outFile, data, 0o644); err != nil { return fmt.Errorf("writing file: %w", err) } @@ -408,7 +411,7 @@ func runExport(cmd *cobra.Command, _ []string) error { if err != nil { return fmt.Errorf("marshaling YAML: %w", err) } - if err := os.WriteFile(outFile, data, 0644); err != nil { + if err := os.WriteFile(outFile, data, 0o644); err != nil { return fmt.Errorf("writing file: %w", err) } @@ -422,7 +425,7 @@ func runExport(cmd *cobra.Command, _ []string) error { if err != nil { return err } - if err := os.WriteFile(outFile, []byte(htmlContent), 0644); err != nil { + if err := os.WriteFile(outFile, []byte(htmlContent), 0o644); err != nil { return fmt.Errorf("writing file: %w", err) } @@ -489,24 +492,36 @@ func buildChartPath(projectID, chartName string) string { // --- CSV export --- -func writeCSV(outFile string, charts []exportedChart) error { +func writeCSV(outFile string, charts []exportedChart) (err error) { f, err := os.Create(outFile) if err != nil { return fmt.Errorf("creating CSV file: %w", err) } - defer f.Close() + defer func() { + if cerr := f.Close(); cerr != nil && err == nil { + err = fmt.Errorf("closing CSV file: %w", cerr) + } + }() w := csv.NewWriter(f) - defer w.Flush() - w.Write([]string{"chart", "index", "date", "value"}) + if werr := w.Write([]string{"chart", "index", "date", "value"}); werr != nil { + return fmt.Errorf("writing CSV header: %w", werr) + } for _, ch := range charts { points := parseDataPoints(ch.Values) for i, pt := range points { - w.Write([]string{ch.Name, fmt.Sprintf("%d", i), pt.date, fmt.Sprintf("%.2f", pt.value)}) + if werr := w.Write([]string{ch.Name, fmt.Sprintf("%d", i), pt.date, fmt.Sprintf("%.2f", pt.value)}); werr != nil { + return fmt.Errorf("writing CSV row: %w", werr) + } } } + + w.Flush() + if werr := w.Error(); werr != nil { + return fmt.Errorf("flushing CSV: %w", werr) + } return nil } @@ -582,10 +597,10 @@ func renderSVG(ch svgChart) string { width := 700.0 height := 300.0 - padL := 70.0 // left padding for y-axis labels + padL := 70.0 // left padding for y-axis labels padR := 20.0 padT := 20.0 - padB := 60.0 // bottom padding for x-axis labels + padB := 60.0 // bottom padding for x-axis labels plotW := width - padL - padR plotH := height - padT - padB @@ -605,7 +620,6 @@ func renderSVG(ch svgChart) string { if valRange == 0 { valRange = 1 minVal -= 0.5 - maxVal += 0.5 } else { minVal -= valRange * 0.05 maxVal += valRange * 0.05 @@ -616,18 +630,18 @@ func renderSVG(ch svgChart) string { } var b strings.Builder - b.WriteString(fmt.Sprintf(``, width, height, width)) + fmt.Fprintf(&b, ``, width, height, width) // Background - b.WriteString(fmt.Sprintf(``, width, height)) + fmt.Fprintf(&b, ``, width, height) // Grid lines (5 horizontal) for i := 0; i <= 4; i++ { y := padT + plotH - (float64(i)/4.0)*plotH val := minVal + (float64(i)/4.0)*valRange - b.WriteString(fmt.Sprintf(``, padL, y, width-padR, y)) + fmt.Fprintf(&b, ``, padL, y, width-padR, y) label := formatAxisLabel(val, ch.YAxis) - b.WriteString(fmt.Sprintf(`%s`, padL-8, y+4, template.HTMLEscapeString(label))) + fmt.Fprintf(&b, `%s`, padL-8, y+4, template.HTMLEscapeString(label)) } // Data polyline + area fill @@ -640,19 +654,19 @@ func renderSVG(ch svgChart) string { } y := padT + plotH - ((p.value-minVal)/valRange)*plotH if i == 0 { - areaPoints.WriteString(fmt.Sprintf("%.1f,%.1f ", x, padT+plotH)) + fmt.Fprintf(&areaPoints, "%.1f,%.1f ", x, padT+plotH) } - polyPoints.WriteString(fmt.Sprintf("%.1f,%.1f ", x, y)) - areaPoints.WriteString(fmt.Sprintf("%.1f,%.1f ", x, y)) + fmt.Fprintf(&polyPoints, "%.1f,%.1f ", x, y) + fmt.Fprintf(&areaPoints, "%.1f,%.1f ", x, y) } // Close area lastX := padL + (float64(n-1)/float64(max(n-1, 1)))*plotW - areaPoints.WriteString(fmt.Sprintf("%.1f,%.1f", lastX, padT+plotH)) + fmt.Fprintf(&areaPoints, "%.1f,%.1f", lastX, padT+plotH) // Area fill - b.WriteString(fmt.Sprintf(``, strings.TrimSpace(areaPoints.String()))) + fmt.Fprintf(&b, ``, strings.TrimSpace(areaPoints.String())) // Line - b.WriteString(fmt.Sprintf(``, strings.TrimSpace(polyPoints.String()))) + fmt.Fprintf(&b, ``, strings.TrimSpace(polyPoints.String())) // Data points (circles) — show all if <=30 points, else every Nth step := 1 @@ -664,7 +678,7 @@ func renderSVG(ch svgChart) string { x := padL + (float64(i)/float64(max(n-1, 1)))*plotW y := padT + plotH - ((p.value-minVal)/valRange)*plotH label := formatAxisLabel(p.value, ch.YAxis) - b.WriteString(fmt.Sprintf(`%s: %s`, x, y, template.HTMLEscapeString(p.date), template.HTMLEscapeString(label))) + fmt.Fprintf(&b, `%s: %s`, x, y, template.HTMLEscapeString(p.date), template.HTMLEscapeString(label)) } // X-axis labels @@ -678,7 +692,7 @@ func renderSVG(ch svgChart) string { if len(date) > 10 { date = date[:10] } - b.WriteString(fmt.Sprintf(`%s`, x, padT+plotH+15, x, padT+plotH+15, template.HTMLEscapeString(date))) + fmt.Fprintf(&b, `%s`, x, padT+plotH+15, x, padT+plotH+15, template.HTMLEscapeString(date)) } b.WriteString("") @@ -727,7 +741,7 @@ type htmlChartData struct { } func renderChartsHTML(report chartExportReport) (string, error) { - var htmlCharts []htmlChartData + htmlCharts := make([]htmlChartData, 0, len(report.Charts)) for _, ch := range report.Charts { points := parseDataPoints(ch.Values) @@ -792,8 +806,8 @@ func renderSummary(raw json.RawMessage) template.HTML { var b strings.Builder b.WriteString(`
`) for key, val := range summary { - label := strings.ReplaceAll(strings.Title(strings.ReplaceAll(key, "_", " ")), " ", " ") - b.WriteString(fmt.Sprintf(`
%s%v
`, template.HTMLEscapeString(label), val)) + label := titleCaser.String(strings.ReplaceAll(key, "_", " ")) + fmt.Fprintf(&b, `
%s%v
`, template.HTMLEscapeString(label), val) } b.WriteString(`
`) return template.HTML(b.String()) @@ -811,20 +825,24 @@ func htmlToPDF(html, pdfPath string) error { if err != nil { return fmt.Errorf("creating temp file: %w", err) } - defer os.Remove(tmpFile.Name()) + defer func() { _ = os.Remove(tmpFile.Name()) }() if _, err := tmpFile.WriteString(html); err != nil { - tmpFile.Close() + _ = tmpFile.Close() return fmt.Errorf("writing temp file: %w", err) } - tmpFile.Close() + if err := tmpFile.Close(); err != nil { + return fmt.Errorf("closing temp file: %w", err) + } absPDF, err := filepath.Abs(pdfPath) if err != nil { absPDF = pdfPath } - cmd := exec.Command(chromePath, + cmd := exec.CommandContext( + context.Background(), + chromePath, "--headless", "--disable-gpu", "--no-sandbox", @@ -837,7 +855,7 @@ func htmlToPDF(html, pdfPath string) error { output.PrintInfo("Generating PDF...") if err := cmd.Run(); err != nil { - return fmt.Errorf("Chrome PDF conversion failed: %w\nTry: rc charts export --format html, then print to PDF from browser", err) + return fmt.Errorf("chrome PDF conversion failed: %w\nTry: rc charts export --format html, then print to PDF from browser", err) } return nil diff --git a/cmd/revenuecat-cli/commands/customers/customers.go b/cmd/revenuecat-cli/commands/customers/customers.go index 6f59abb..77e5759 100644 --- a/cmd/revenuecat-cli/commands/customers/customers.go +++ b/cmd/revenuecat-cli/commands/customers/customers.go @@ -124,13 +124,13 @@ var assignOfferingCmd = &cobra.Command{ func init() { // Get flags getCmd.Flags().StringVar(&customerID, "customer-id", "", "customer ID") - getCmd.MarkFlagRequired("customer-id") + _ = getCmd.MarkFlagRequired("customer-id") // Delete flags var confirm bool deleteCmd.Flags().StringVar(&customerID, "customer-id", "", "customer ID") deleteCmd.Flags().BoolVar(&confirm, "confirm", false, "confirm deletion") - deleteCmd.MarkFlagRequired("customer-id") + _ = deleteCmd.MarkFlagRequired("customer-id") // List flags listCmd.Flags().IntVar(&limit, "limit", 20, "number of results per page") @@ -139,75 +139,75 @@ func init() { // Create flags createCmd.Flags().StringVar(&customerID, "customer-id", "", "customer app_user_id") - createCmd.MarkFlagRequired("customer-id") + _ = createCmd.MarkFlagRequired("customer-id") // List active entitlements flags listActiveEntitlementsCmd.Flags().StringVar(&customerID, "customer-id", "", "customer ID") listActiveEntitlementsCmd.Flags().IntVar(&limit, "limit", 20, "number of results per page") listActiveEntitlementsCmd.Flags().StringVar(&startAfter, "starting-after", "", "cursor for pagination") listActiveEntitlementsCmd.Flags().BoolVar(&allPages, "all", false, "fetch all pages") - listActiveEntitlementsCmd.MarkFlagRequired("customer-id") + _ = listActiveEntitlementsCmd.MarkFlagRequired("customer-id") // List aliases flags listAliasesCmd.Flags().StringVar(&customerID, "customer-id", "", "customer ID") - listAliasesCmd.MarkFlagRequired("customer-id") + _ = listAliasesCmd.MarkFlagRequired("customer-id") // List attributes flags listAttributesCmd.Flags().StringVar(&customerID, "customer-id", "", "customer ID") - listAttributesCmd.MarkFlagRequired("customer-id") + _ = listAttributesCmd.MarkFlagRequired("customer-id") // Set attributes flags setAttributesCmd.Flags().StringVar(&customerID, "customer-id", "", "customer ID") setAttributesCmd.Flags().StringVar(&attributes, "attributes", "", "JSON attributes to set") - setAttributesCmd.MarkFlagRequired("customer-id") - setAttributesCmd.MarkFlagRequired("attributes") + _ = setAttributesCmd.MarkFlagRequired("customer-id") + _ = setAttributesCmd.MarkFlagRequired("attributes") // List subscriptions flags listSubscriptionsCmd.Flags().StringVar(&customerID, "customer-id", "", "customer ID") listSubscriptionsCmd.Flags().IntVar(&limit, "limit", 20, "number of results per page") listSubscriptionsCmd.Flags().StringVar(&startAfter, "starting-after", "", "cursor for pagination") listSubscriptionsCmd.Flags().BoolVar(&allPages, "all", false, "fetch all pages") - listSubscriptionsCmd.MarkFlagRequired("customer-id") + _ = listSubscriptionsCmd.MarkFlagRequired("customer-id") // List purchases flags listPurchasesCmd.Flags().StringVar(&customerID, "customer-id", "", "customer ID") listPurchasesCmd.Flags().IntVar(&limit, "limit", 20, "number of results per page") listPurchasesCmd.Flags().StringVar(&startAfter, "starting-after", "", "cursor for pagination") listPurchasesCmd.Flags().BoolVar(&allPages, "all", false, "fetch all pages") - listPurchasesCmd.MarkFlagRequired("customer-id") + _ = listPurchasesCmd.MarkFlagRequired("customer-id") // List invoices flags listInvoicesCmd.Flags().StringVar(&customerID, "customer-id", "", "customer ID") listInvoicesCmd.Flags().IntVar(&limit, "limit", 20, "number of results per page") listInvoicesCmd.Flags().StringVar(&startAfter, "starting-after", "", "cursor for pagination") listInvoicesCmd.Flags().BoolVar(&allPages, "all", false, "fetch all pages") - listInvoicesCmd.MarkFlagRequired("customer-id") + _ = listInvoicesCmd.MarkFlagRequired("customer-id") // Transfer flags transferCmd.Flags().StringVar(&customerID, "customer-id", "", "customer ID") transferCmd.Flags().StringVar(&targetID, "target-id", "", "target customer ID") - transferCmd.MarkFlagRequired("customer-id") - transferCmd.MarkFlagRequired("target-id") + _ = transferCmd.MarkFlagRequired("customer-id") + _ = transferCmd.MarkFlagRequired("target-id") // Grant entitlement flags grantEntitlementCmd.Flags().StringVar(&customerID, "customer-id", "", "customer ID") grantEntitlementCmd.Flags().StringVar(&entitlementID, "entitlement-id", "", "entitlement ID") grantEntitlementCmd.Flags().Int64Var(&expiresAt, "expires-at", 0, "expiry date in ms since epoch (required by the API)") - grantEntitlementCmd.MarkFlagRequired("customer-id") - grantEntitlementCmd.MarkFlagRequired("entitlement-id") - grantEntitlementCmd.MarkFlagRequired("expires-at") + _ = grantEntitlementCmd.MarkFlagRequired("customer-id") + _ = grantEntitlementCmd.MarkFlagRequired("entitlement-id") + _ = grantEntitlementCmd.MarkFlagRequired("expires-at") // Revoke entitlement flags revokeEntitlementCmd.Flags().StringVar(&customerID, "customer-id", "", "customer ID") revokeEntitlementCmd.Flags().StringVar(&entitlementID, "entitlement-id", "", "entitlement ID") - revokeEntitlementCmd.MarkFlagRequired("customer-id") - revokeEntitlementCmd.MarkFlagRequired("entitlement-id") + _ = revokeEntitlementCmd.MarkFlagRequired("customer-id") + _ = revokeEntitlementCmd.MarkFlagRequired("entitlement-id") // Assign offering flags assignOfferingCmd.Flags().StringVar(&customerID, "customer-id", "", "customer ID") assignOfferingCmd.Flags().StringVar(&offeringID, "offering-id", "", "offering ID") - assignOfferingCmd.MarkFlagRequired("customer-id") - assignOfferingCmd.MarkFlagRequired("offering-id") + _ = assignOfferingCmd.MarkFlagRequired("customer-id") + _ = assignOfferingCmd.MarkFlagRequired("offering-id") CustomersCmd.AddCommand(getCmd) CustomersCmd.AddCommand(deleteCmd) diff --git a/cmd/revenuecat-cli/commands/diff/diff.go b/cmd/revenuecat-cli/commands/diff/diff.go index 2f3230e..d76b54f 100644 --- a/cmd/revenuecat-cli/commands/diff/diff.go +++ b/cmd/revenuecat-cli/commands/diff/diff.go @@ -28,8 +28,8 @@ var DiffCmd = &cobra.Command{ func init() { DiffCmd.Flags().StringVar(&source, "source", "", "source project ID") DiffCmd.Flags().StringVar(&target, "target", "", "target project ID") - DiffCmd.MarkFlagRequired("source") - DiffCmd.MarkFlagRequired("target") + _ = DiffCmd.MarkFlagRequired("source") + _ = DiffCmd.MarkFlagRequired("target") } type DiffResult struct { diff --git a/cmd/revenuecat-cli/commands/doctor/doctor.go b/cmd/revenuecat-cli/commands/doctor/doctor.go index 64d31a4..7656941 100644 --- a/cmd/revenuecat-cli/commands/doctor/doctor.go +++ b/cmd/revenuecat-cli/commands/doctor/doctor.go @@ -125,10 +125,11 @@ func runDoctor(cmd *cobra.Command, args []string) error { allOK := true for _, r := range results { icon := "✓" - if r.Status == "FAIL" { + switch r.Status { + case "FAIL": icon = "✗" allOK = false - } else if r.Status == "WARN" || r.Status == "SKIP" { + case "WARN", "SKIP": icon = "!" } output.PrintInfo("%s %s: %s (%s)", icon, r.Check, r.Status, r.Detail) diff --git a/cmd/revenuecat-cli/commands/entitlements/entitlements.go b/cmd/revenuecat-cli/commands/entitlements/entitlements.go index 11fb22b..d3322a3 100644 --- a/cmd/revenuecat-cli/commands/entitlements/entitlements.go +++ b/cmd/revenuecat-cli/commands/entitlements/entitlements.go @@ -85,41 +85,41 @@ func init() { listCmd.Flags().BoolVar(&allPages, "all", false, "fetch all pages") getCmd.Flags().StringVar(&entitlementID, "entitlement-id", "", "entitlement ID") - getCmd.MarkFlagRequired("entitlement-id") - getCmd.RegisterFlagCompletionFunc("entitlement-id", completion.EntitlementIDs()) + _ = getCmd.MarkFlagRequired("entitlement-id") + _ = getCmd.RegisterFlagCompletionFunc("entitlement-id", completion.EntitlementIDs()) createCmd.Flags().StringVar(&lookupKey, "lookup-key", "", "entitlement lookup key") createCmd.Flags().StringVar(&displayName, "display-name", "", "entitlement display name") - createCmd.MarkFlagRequired("lookup-key") - createCmd.MarkFlagRequired("display-name") + _ = createCmd.MarkFlagRequired("lookup-key") + _ = createCmd.MarkFlagRequired("display-name") updateCmd.Flags().StringVar(&entitlementID, "entitlement-id", "", "entitlement ID") updateCmd.Flags().StringVar(&displayName, "display-name", "", "new display name") - updateCmd.MarkFlagRequired("entitlement-id") - updateCmd.RegisterFlagCompletionFunc("entitlement-id", completion.EntitlementIDs()) - updateCmd.MarkFlagRequired("display-name") + _ = updateCmd.MarkFlagRequired("entitlement-id") + _ = updateCmd.RegisterFlagCompletionFunc("entitlement-id", completion.EntitlementIDs()) + _ = updateCmd.MarkFlagRequired("display-name") var confirm bool deleteCmd.Flags().StringVar(&entitlementID, "entitlement-id", "", "entitlement ID") deleteCmd.Flags().BoolVar(&confirm, "confirm", false, "confirm deletion") - deleteCmd.MarkFlagRequired("entitlement-id") - deleteCmd.RegisterFlagCompletionFunc("entitlement-id", completion.EntitlementIDs()) + _ = deleteCmd.MarkFlagRequired("entitlement-id") + _ = deleteCmd.RegisterFlagCompletionFunc("entitlement-id", completion.EntitlementIDs()) listProductsCmd.Flags().StringVar(&entitlementID, "entitlement-id", "", "entitlement ID") - listProductsCmd.MarkFlagRequired("entitlement-id") - listProductsCmd.RegisterFlagCompletionFunc("entitlement-id", completion.EntitlementIDs()) + _ = listProductsCmd.MarkFlagRequired("entitlement-id") + _ = listProductsCmd.RegisterFlagCompletionFunc("entitlement-id", completion.EntitlementIDs()) attachProductsCmd.Flags().StringVar(&entitlementID, "entitlement-id", "", "entitlement ID") attachProductsCmd.Flags().StringSliceVar(&productIDs, "product-ids", nil, "product IDs to attach") - attachProductsCmd.MarkFlagRequired("entitlement-id") - attachProductsCmd.RegisterFlagCompletionFunc("entitlement-id", completion.EntitlementIDs()) - attachProductsCmd.MarkFlagRequired("product-ids") + _ = attachProductsCmd.MarkFlagRequired("entitlement-id") + _ = attachProductsCmd.RegisterFlagCompletionFunc("entitlement-id", completion.EntitlementIDs()) + _ = attachProductsCmd.MarkFlagRequired("product-ids") detachProductsCmd.Flags().StringVar(&entitlementID, "entitlement-id", "", "entitlement ID") detachProductsCmd.Flags().StringSliceVar(&productIDs, "product-ids", nil, "product IDs to detach") - detachProductsCmd.MarkFlagRequired("entitlement-id") - detachProductsCmd.RegisterFlagCompletionFunc("entitlement-id", completion.EntitlementIDs()) - detachProductsCmd.MarkFlagRequired("product-ids") + _ = detachProductsCmd.MarkFlagRequired("entitlement-id") + _ = detachProductsCmd.RegisterFlagCompletionFunc("entitlement-id", completion.EntitlementIDs()) + _ = detachProductsCmd.MarkFlagRequired("product-ids") EntitlementsCmd.AddCommand(listCmd) EntitlementsCmd.AddCommand(getCmd) diff --git a/cmd/revenuecat-cli/commands/exportcmd/exportcmd.go b/cmd/revenuecat-cli/commands/exportcmd/exportcmd.go index cc9e4c1..23508dc 100644 --- a/cmd/revenuecat-cli/commands/exportcmd/exportcmd.go +++ b/cmd/revenuecat-cli/commands/exportcmd/exportcmd.go @@ -41,13 +41,13 @@ func init() { ImportCmd.Flags().StringVar(&importFile, "file", "", "input YAML file path") ImportCmd.Flags().BoolVar(&confirm, "confirm", false, "confirm import (required for safety)") - ImportCmd.MarkFlagRequired("file") + _ = ImportCmd.MarkFlagRequired("file") } type ProjectConfig struct { - Version string `yaml:"version" json:"version"` - ProjectID string `yaml:"project_id" json:"project_id"` - ExportedAt string `yaml:"exported_at" json:"exported_at"` + Version string `yaml:"version" json:"version"` + ProjectID string `yaml:"project_id" json:"project_id"` + ExportedAt string `yaml:"exported_at" json:"exported_at"` Entitlements []EntitlementExport `yaml:"entitlements" json:"entitlements"` Offerings []OfferingExport `yaml:"offerings" json:"offerings"` } @@ -183,7 +183,7 @@ func runExport(cmd *cobra.Command, args []string) error { return fmt.Errorf("marshaling YAML: %w", err) } - if err := os.WriteFile(exportFile, data, 0644); err != nil { + if err := os.WriteFile(exportFile, data, 0o644); err != nil { return fmt.Errorf("writing file: %w", err) } diff --git a/cmd/revenuecat-cli/commands/init.go b/cmd/revenuecat-cli/commands/init.go index ab1eaae..da3f9d4 100644 --- a/cmd/revenuecat-cli/commands/init.go +++ b/cmd/revenuecat-cli/commands/init.go @@ -2,9 +2,9 @@ package commands import ( "github.com/AndroidPoet/revenuecat-cli/cmd/revenuecat-cli/commands/apps" - "github.com/AndroidPoet/revenuecat-cli/cmd/revenuecat-cli/commands/charts" "github.com/AndroidPoet/revenuecat-cli/cmd/revenuecat-cli/commands/auditlogs" "github.com/AndroidPoet/revenuecat-cli/cmd/revenuecat-cli/commands/auth" + "github.com/AndroidPoet/revenuecat-cli/cmd/revenuecat-cli/commands/charts" "github.com/AndroidPoet/revenuecat-cli/cmd/revenuecat-cli/commands/completion" "github.com/AndroidPoet/revenuecat-cli/cmd/revenuecat-cli/commands/customers" "github.com/AndroidPoet/revenuecat-cli/cmd/revenuecat-cli/commands/diff" diff --git a/cmd/revenuecat-cli/commands/initcmd/initcmd.go b/cmd/revenuecat-cli/commands/initcmd/initcmd.go index 8c45c66..30842a8 100644 --- a/cmd/revenuecat-cli/commands/initcmd/initcmd.go +++ b/cmd/revenuecat-cli/commands/initcmd/initcmd.go @@ -40,7 +40,7 @@ func init() { InitCmd.Flags().StringVar(&initProject, "project", "", "RevenueCat project ID") InitCmd.Flags().StringVar(&initOutput, "output", "json", "default output format") InitCmd.Flags().BoolVar(&initForce, "force", false, "overwrite existing config") - InitCmd.MarkFlagRequired("project") + _ = InitCmd.MarkFlagRequired("project") } func runInit(cmd *cobra.Command, args []string) error { @@ -61,7 +61,7 @@ func runInit(cmd *cobra.Command, args []string) error { return fmt.Errorf("failed to marshal config: %w", err) } - if err := os.WriteFile(configFile, data, 0644); err != nil { + if err := os.WriteFile(configFile, data, 0o644); err != nil { return fmt.Errorf("failed to write %s: %w", configFileName, err) } diff --git a/cmd/revenuecat-cli/commands/offerings/offerings.go b/cmd/revenuecat-cli/commands/offerings/offerings.go index 90e3643..0b8aaef 100644 --- a/cmd/revenuecat-cli/commands/offerings/offerings.go +++ b/cmd/revenuecat-cli/commands/offerings/offerings.go @@ -69,25 +69,25 @@ func init() { createCmd.Flags().StringVar(&lookupKey, "lookup-key", "", "offering lookup key") createCmd.Flags().StringVar(&displayName, "display-name", "", "offering display name") createCmd.Flags().StringVar(&metadata, "metadata", "", "JSON metadata string") - createCmd.MarkFlagRequired("lookup-key") - createCmd.MarkFlagRequired("display-name") + _ = createCmd.MarkFlagRequired("lookup-key") + _ = createCmd.MarkFlagRequired("display-name") updateCmd.Flags().StringVar(&offeringID, "offering-id", "", "offering ID") updateCmd.Flags().StringVar(&displayName, "display-name", "", "new display name") updateCmd.Flags().BoolVar(&isCurrent, "is-current", false, "set as current offering") updateCmd.Flags().StringVar(&metadata, "metadata", "", "JSON metadata string") - updateCmd.MarkFlagRequired("offering-id") - updateCmd.RegisterFlagCompletionFunc("offering-id", completion.OfferingIDs()) + _ = updateCmd.MarkFlagRequired("offering-id") + _ = updateCmd.RegisterFlagCompletionFunc("offering-id", completion.OfferingIDs()) getCmd.Flags().StringVar(&offeringID, "offering-id", "", "offering ID") - getCmd.MarkFlagRequired("offering-id") - getCmd.RegisterFlagCompletionFunc("offering-id", completion.OfferingIDs()) + _ = getCmd.MarkFlagRequired("offering-id") + _ = getCmd.RegisterFlagCompletionFunc("offering-id", completion.OfferingIDs()) var confirm bool deleteCmd.Flags().StringVar(&offeringID, "offering-id", "", "offering ID") deleteCmd.Flags().BoolVar(&confirm, "confirm", false, "confirm deletion") - deleteCmd.MarkFlagRequired("offering-id") - deleteCmd.RegisterFlagCompletionFunc("offering-id", completion.OfferingIDs()) + _ = deleteCmd.MarkFlagRequired("offering-id") + _ = deleteCmd.RegisterFlagCompletionFunc("offering-id", completion.OfferingIDs()) OfferingsCmd.AddCommand(listCmd) OfferingsCmd.AddCommand(createCmd) diff --git a/cmd/revenuecat-cli/commands/packages/packages.go b/cmd/revenuecat-cli/commands/packages/packages.go index 02edd1f..e774452 100644 --- a/cmd/revenuecat-cli/commands/packages/packages.go +++ b/cmd/revenuecat-cli/commands/packages/packages.go @@ -83,42 +83,42 @@ func init() { listCmd.Flags().IntVar(&limit, "limit", 20, "number of results per page") listCmd.Flags().StringVar(&startAfter, "starting-after", "", "cursor for pagination") listCmd.Flags().BoolVar(&allPages, "all", false, "fetch all pages") - listCmd.MarkFlagRequired("offering-id") + _ = listCmd.MarkFlagRequired("offering-id") createCmd.Flags().StringVar(&offeringID, "offering-id", "", "offering ID") createCmd.Flags().StringVar(&lookupKey, "lookup-key", "", "package lookup key") createCmd.Flags().StringVar(&displayName, "display-name", "", "package display name") - createCmd.MarkFlagRequired("offering-id") - createCmd.MarkFlagRequired("lookup-key") - createCmd.MarkFlagRequired("display-name") + _ = createCmd.MarkFlagRequired("offering-id") + _ = createCmd.MarkFlagRequired("lookup-key") + _ = createCmd.MarkFlagRequired("display-name") attachProductsCmd.Flags().StringVar(&packageID, "package-id", "", "package ID") attachProductsCmd.Flags().StringSliceVar(&productIDs, "product-ids", nil, "product IDs to attach") - attachProductsCmd.MarkFlagRequired("package-id") - attachProductsCmd.MarkFlagRequired("product-ids") + _ = attachProductsCmd.MarkFlagRequired("package-id") + _ = attachProductsCmd.MarkFlagRequired("product-ids") detachProductsCmd.Flags().StringVar(&packageID, "package-id", "", "package ID") detachProductsCmd.Flags().StringSliceVar(&productIDs, "product-ids", nil, "product IDs to detach") - detachProductsCmd.MarkFlagRequired("package-id") - detachProductsCmd.MarkFlagRequired("product-ids") + _ = detachProductsCmd.MarkFlagRequired("package-id") + _ = detachProductsCmd.MarkFlagRequired("product-ids") getCmd.Flags().StringVar(&packageID, "package-id", "", "package ID") - getCmd.MarkFlagRequired("package-id") + _ = getCmd.MarkFlagRequired("package-id") updateCmd.Flags().StringVar(&packageID, "package-id", "", "package ID") updateCmd.Flags().StringVar(&displayName, "display-name", "", "new display name") - updateCmd.MarkFlagRequired("package-id") + _ = updateCmd.MarkFlagRequired("package-id") var confirm bool deleteCmd.Flags().StringVar(&packageID, "package-id", "", "package ID") deleteCmd.Flags().BoolVar(&confirm, "confirm", false, "confirm deletion") - deleteCmd.MarkFlagRequired("package-id") + _ = deleteCmd.MarkFlagRequired("package-id") listProductsCmd.Flags().StringVar(&packageID, "package-id", "", "package ID") listProductsCmd.Flags().IntVar(&limit, "limit", 20, "number of results per page") listProductsCmd.Flags().StringVar(&startAfter, "starting-after", "", "cursor for pagination") listProductsCmd.Flags().BoolVar(&allPages, "all", false, "fetch all pages") - listProductsCmd.MarkFlagRequired("package-id") + _ = listProductsCmd.MarkFlagRequired("package-id") PackagesCmd.AddCommand(listCmd) PackagesCmd.AddCommand(createCmd) diff --git a/cmd/revenuecat-cli/commands/paywalls/paywalls.go b/cmd/revenuecat-cli/commands/paywalls/paywalls.go index 83b3faf..9848730 100644 --- a/cmd/revenuecat-cli/commands/paywalls/paywalls.go +++ b/cmd/revenuecat-cli/commands/paywalls/paywalls.go @@ -53,19 +53,19 @@ var deleteCmd = &cobra.Command{ func init() { createCmd.Flags().StringVar(&offeringID, "offering-id", "", "offering ID to create paywall for") - createCmd.MarkFlagRequired("offering-id") + _ = createCmd.MarkFlagRequired("offering-id") listCmd.Flags().IntVar(&limit, "limit", 20, "number of results per page") listCmd.Flags().StringVar(&startAfter, "starting-after", "", "cursor for pagination") listCmd.Flags().BoolVar(&allPages, "all", false, "fetch all pages") getCmd.Flags().StringVar(&paywallID, "paywall-id", "", "paywall ID") - getCmd.MarkFlagRequired("paywall-id") + _ = getCmd.MarkFlagRequired("paywall-id") var confirm bool deleteCmd.Flags().StringVar(&paywallID, "paywall-id", "", "paywall ID") deleteCmd.Flags().BoolVar(&confirm, "confirm", false, "confirm deletion") - deleteCmd.MarkFlagRequired("paywall-id") + _ = deleteCmd.MarkFlagRequired("paywall-id") PaywallsCmd.AddCommand(createCmd) PaywallsCmd.AddCommand(listCmd) @@ -110,8 +110,8 @@ func runCreate(cmd *cobra.Command, args []string) error { } type PaywallInfo struct { - ID string `json:"id"` - CreatedAt interface{} `json:"created_at,omitempty"` + ID string `json:"id"` + CreatedAt interface{} `json:"created_at,omitempty"` } func runList(cmd *cobra.Command, args []string) error { @@ -152,7 +152,7 @@ func runList(cmd *cobra.Command, args []string) error { var resp struct { Items []PaywallInfo `json:"items"` - NextPage string `json:"next_page,omitempty"` + NextPage string `json:"next_page,omitempty"` } if err := client.Get(ctx, path+query, &resp); err != nil { return err diff --git a/cmd/revenuecat-cli/commands/products/products.go b/cmd/revenuecat-cli/commands/products/products.go index 0887d63..65af64e 100644 --- a/cmd/revenuecat-cli/commands/products/products.go +++ b/cmd/revenuecat-cli/commands/products/products.go @@ -62,20 +62,20 @@ func init() { createCmd.Flags().StringVar(&storeIdentifier, "store-identifier", "", "store product identifier") createCmd.Flags().StringVar(&productType, "type", "", "product type (subscription, one_time)") createCmd.Flags().StringVar(&appID, "app-id", "", "app ID this product belongs to") - createCmd.MarkFlagRequired("store-identifier") - createCmd.MarkFlagRequired("type") - createCmd.MarkFlagRequired("app-id") - createCmd.RegisterFlagCompletionFunc("app-id", completion.AppIDs()) + _ = createCmd.MarkFlagRequired("store-identifier") + _ = createCmd.MarkFlagRequired("type") + _ = createCmd.MarkFlagRequired("app-id") + _ = createCmd.RegisterFlagCompletionFunc("app-id", completion.AppIDs()) getCmd.Flags().StringVar(&productID, "product-id", "", "product ID") - getCmd.MarkFlagRequired("product-id") - getCmd.RegisterFlagCompletionFunc("product-id", completion.ProductIDs()) + _ = getCmd.MarkFlagRequired("product-id") + _ = getCmd.RegisterFlagCompletionFunc("product-id", completion.ProductIDs()) var confirm bool deleteCmd.Flags().StringVar(&productID, "product-id", "", "product ID") deleteCmd.Flags().BoolVar(&confirm, "confirm", false, "confirm deletion") - deleteCmd.MarkFlagRequired("product-id") - deleteCmd.RegisterFlagCompletionFunc("product-id", completion.ProductIDs()) + _ = deleteCmd.MarkFlagRequired("product-id") + _ = deleteCmd.RegisterFlagCompletionFunc("product-id", completion.ProductIDs()) ProductsCmd.AddCommand(listCmd) ProductsCmd.AddCommand(createCmd) @@ -84,11 +84,11 @@ func init() { } type ProductInfo struct { - ID string `json:"id"` - StoreIdentifier string `json:"store_identifier"` - Type string `json:"type"` - AppID string `json:"app_id,omitempty"` - CreatedAt interface{} `json:"created_at,omitempty"` + ID string `json:"id"` + StoreIdentifier string `json:"store_identifier"` + Type string `json:"type"` + AppID string `json:"app_id,omitempty"` + CreatedAt interface{} `json:"created_at,omitempty"` } func parseTimeout() time.Duration { @@ -137,7 +137,7 @@ func runList(cmd *cobra.Command, args []string) error { var resp struct { Items []ProductInfo `json:"items"` - NextPage string `json:"next_page,omitempty"` + NextPage string `json:"next_page,omitempty"` } if err := client.Get(ctx, path+query, &resp); err != nil { return err diff --git a/cmd/revenuecat-cli/commands/projects/projects.go b/cmd/revenuecat-cli/commands/projects/projects.go index eb46046..8058745 100644 --- a/cmd/revenuecat-cli/commands/projects/projects.go +++ b/cmd/revenuecat-cli/commands/projects/projects.go @@ -44,16 +44,16 @@ func init() { listCmd.Flags().BoolVar(&allPages, "all", false, "fetch all pages") createCmd.Flags().StringVar(&projectName, "name", "", "project name") - createCmd.MarkFlagRequired("name") + _ = createCmd.MarkFlagRequired("name") ProjectsCmd.AddCommand(listCmd) ProjectsCmd.AddCommand(createCmd) } type ProjectInfo struct { - ID string `json:"id"` - Name string `json:"name"` - CreatedAt interface{} `json:"created_at,omitempty"` + ID string `json:"id"` + Name string `json:"name"` + CreatedAt interface{} `json:"created_at,omitempty"` } func parseTimeout() time.Duration { diff --git a/cmd/revenuecat-cli/commands/purchases/purchases.go b/cmd/revenuecat-cli/commands/purchases/purchases.go index fa73622..a545589 100644 --- a/cmd/revenuecat-cli/commands/purchases/purchases.go +++ b/cmd/revenuecat-cli/commands/purchases/purchases.go @@ -11,9 +11,7 @@ import ( "github.com/AndroidPoet/revenuecat-cli/internal/output" ) -var ( - purchaseID string -) +var purchaseID string // PurchasesCmd manages purchases var PurchasesCmd = &cobra.Command{ @@ -42,15 +40,15 @@ var refundCmd = &cobra.Command{ func init() { getCmd.Flags().StringVar(&purchaseID, "purchase-id", "", "purchase ID") - getCmd.MarkFlagRequired("purchase-id") + _ = getCmd.MarkFlagRequired("purchase-id") listEntitlementsCmd.Flags().StringVar(&purchaseID, "purchase-id", "", "purchase ID") - listEntitlementsCmd.MarkFlagRequired("purchase-id") + _ = listEntitlementsCmd.MarkFlagRequired("purchase-id") var confirm bool refundCmd.Flags().StringVar(&purchaseID, "purchase-id", "", "purchase ID") refundCmd.Flags().BoolVar(&confirm, "confirm", false, "confirm refund") - refundCmd.MarkFlagRequired("purchase-id") + _ = refundCmd.MarkFlagRequired("purchase-id") PurchasesCmd.AddCommand(getCmd) PurchasesCmd.AddCommand(listEntitlementsCmd) diff --git a/cmd/revenuecat-cli/commands/report/report.go b/cmd/revenuecat-cli/commands/report/report.go index 2c60138..36c720e 100644 --- a/cmd/revenuecat-cli/commands/report/report.go +++ b/cmd/revenuecat-cli/commands/report/report.go @@ -2,6 +2,7 @@ package report import ( "bytes" + "context" "encoding/json" "fmt" "html/template" @@ -40,13 +41,13 @@ func init() { // --- Data types --- type ProjectReport struct { - GeneratedAt string `json:"generated_at" yaml:"generated_at"` - ProjectID string `json:"project_id" yaml:"project_id"` - Summary ReportSummary `json:"summary" yaml:"summary"` - Apps []AppData `json:"apps" yaml:"apps"` - Products []ProductData `json:"products" yaml:"products"` + GeneratedAt string `json:"generated_at" yaml:"generated_at"` + ProjectID string `json:"project_id" yaml:"project_id"` + Summary ReportSummary `json:"summary" yaml:"summary"` + Apps []AppData `json:"apps" yaml:"apps"` + Products []ProductData `json:"products" yaml:"products"` Entitlements []EntitlementData `json:"entitlements" yaml:"entitlements"` - Offerings []OfferingData `json:"offerings" yaml:"offerings"` + Offerings []OfferingData `json:"offerings" yaml:"offerings"` } type ReportSummary struct { @@ -285,7 +286,7 @@ func runReport(cmd *cobra.Command, args []string) error { if err != nil { return fmt.Errorf("marshaling JSON: %w", err) } - if err := os.WriteFile(reportFile, data, 0644); err != nil { + if err := os.WriteFile(reportFile, data, 0o644); err != nil { return fmt.Errorf("writing file: %w", err) } @@ -294,7 +295,7 @@ func runReport(cmd *cobra.Command, args []string) error { if err != nil { return fmt.Errorf("marshaling YAML: %w", err) } - if err := os.WriteFile(reportFile, data, 0644); err != nil { + if err := os.WriteFile(reportFile, data, 0o644); err != nil { return fmt.Errorf("writing file: %w", err) } @@ -303,7 +304,7 @@ func runReport(cmd *cobra.Command, args []string) error { if err != nil { return fmt.Errorf("rendering HTML: %w", err) } - if err := os.WriteFile(reportFile, []byte(html), 0644); err != nil { + if err := os.WriteFile(reportFile, []byte(html), 0o644); err != nil { return fmt.Errorf("writing file: %w", err) } @@ -388,13 +389,15 @@ func htmlToPDF(html, pdfPath string) error { if err != nil { return fmt.Errorf("creating temp file: %w", err) } - defer os.Remove(tmpFile.Name()) + defer func() { _ = os.Remove(tmpFile.Name()) }() if _, err := tmpFile.WriteString(html); err != nil { - tmpFile.Close() + _ = tmpFile.Close() return fmt.Errorf("writing temp file: %w", err) } - tmpFile.Close() + if err := tmpFile.Close(); err != nil { + return fmt.Errorf("closing temp file: %w", err) + } // Convert absolute path for the PDF output absPDF, err := filepath.Abs(pdfPath) @@ -403,7 +406,9 @@ func htmlToPDF(html, pdfPath string) error { } // Run Chrome headless - cmd := exec.Command(chromePath, + cmd := exec.CommandContext( + context.Background(), + chromePath, "--headless", "--disable-gpu", "--no-sandbox", @@ -416,7 +421,7 @@ func htmlToPDF(html, pdfPath string) error { output.PrintInfo("Generating PDF...") if err := cmd.Run(); err != nil { - return fmt.Errorf("Chrome PDF conversion failed: %w\nTry: rc report --format html, then print to PDF from browser", err) + return fmt.Errorf("chrome PDF conversion failed: %w\nTry: rc report --format html, then print to PDF from browser", err) } return nil diff --git a/cmd/revenuecat-cli/commands/root.go b/cmd/revenuecat-cli/commands/root.go index 3a388ec..dd2f4b3 100644 --- a/cmd/revenuecat-cli/commands/root.go +++ b/cmd/revenuecat-cli/commands/root.go @@ -107,19 +107,19 @@ func init() { rootCmd.PersistentFlags().BoolVar(&dryRun, "dry-run", false, "preview changes without applying") // Bind to viper - viper.BindPFlag("project", rootCmd.PersistentFlags().Lookup("project")) - viper.BindPFlag("profile", rootCmd.PersistentFlags().Lookup("profile")) - viper.BindPFlag("output", rootCmd.PersistentFlags().Lookup("output")) - viper.BindPFlag("debug", rootCmd.PersistentFlags().Lookup("debug")) - viper.BindPFlag("timeout", rootCmd.PersistentFlags().Lookup("timeout")) + _ = viper.BindPFlag("project", rootCmd.PersistentFlags().Lookup("project")) + _ = viper.BindPFlag("profile", rootCmd.PersistentFlags().Lookup("profile")) + _ = viper.BindPFlag("output", rootCmd.PersistentFlags().Lookup("output")) + _ = viper.BindPFlag("debug", rootCmd.PersistentFlags().Lookup("debug")) + _ = viper.BindPFlag("timeout", rootCmd.PersistentFlags().Lookup("timeout")) // Environment variable bindings - viper.BindEnv("project", "RC_PROJECT") - viper.BindEnv("profile", "RC_PROFILE") - viper.BindEnv("output", "RC_OUTPUT") - viper.BindEnv("debug", "RC_DEBUG") - viper.BindEnv("timeout", "RC_TIMEOUT") - viper.BindEnv("api_key", "RC_API_KEY") + _ = viper.BindEnv("project", "RC_PROJECT") + _ = viper.BindEnv("profile", "RC_PROFILE") + _ = viper.BindEnv("output", "RC_OUTPUT") + _ = viper.BindEnv("debug", "RC_DEBUG") + _ = viper.BindEnv("timeout", "RC_TIMEOUT") + _ = viper.BindEnv("api_key", "RC_API_KEY") // Add version command rootCmd.AddCommand(&cobra.Command{ diff --git a/cmd/revenuecat-cli/commands/subscriptions/subscriptions.go b/cmd/revenuecat-cli/commands/subscriptions/subscriptions.go index 843d0ae..61ed1fb 100644 --- a/cmd/revenuecat-cli/commands/subscriptions/subscriptions.go +++ b/cmd/revenuecat-cli/commands/subscriptions/subscriptions.go @@ -11,9 +11,7 @@ import ( "github.com/AndroidPoet/revenuecat-cli/internal/output" ) -var ( - subscriptionID string -) +var subscriptionID string // SubscriptionsCmd manages subscriptions var SubscriptionsCmd = &cobra.Command{ @@ -48,19 +46,19 @@ var refundCmd = &cobra.Command{ func init() { getCmd.Flags().StringVar(&subscriptionID, "subscription-id", "", "subscription ID") - getCmd.MarkFlagRequired("subscription-id") + _ = getCmd.MarkFlagRequired("subscription-id") listEntitlementsCmd.Flags().StringVar(&subscriptionID, "subscription-id", "", "subscription ID") - listEntitlementsCmd.MarkFlagRequired("subscription-id") + _ = listEntitlementsCmd.MarkFlagRequired("subscription-id") var confirm bool cancelCmd.Flags().StringVar(&subscriptionID, "subscription-id", "", "subscription ID") cancelCmd.Flags().BoolVar(&confirm, "confirm", false, "confirm cancellation") - cancelCmd.MarkFlagRequired("subscription-id") + _ = cancelCmd.MarkFlagRequired("subscription-id") refundCmd.Flags().StringVar(&subscriptionID, "subscription-id", "", "subscription ID") refundCmd.Flags().BoolVar(&confirm, "confirm", false, "confirm refund") - refundCmd.MarkFlagRequired("subscription-id") + _ = refundCmd.MarkFlagRequired("subscription-id") SubscriptionsCmd.AddCommand(getCmd) SubscriptionsCmd.AddCommand(listEntitlementsCmd) diff --git a/cmd/revenuecat-cli/commands/webhooks/webhooks.go b/cmd/revenuecat-cli/commands/webhooks/webhooks.go index 8858cb6..b18e608 100644 --- a/cmd/revenuecat-cli/commands/webhooks/webhooks.go +++ b/cmd/revenuecat-cli/commands/webhooks/webhooks.go @@ -44,7 +44,7 @@ func init() { listCmd.Flags().BoolVar(&allPages, "all", false, "fetch all pages") createCmd.Flags().StringVar(&webhookURL, "url", "", "webhook URL") - createCmd.MarkFlagRequired("url") + _ = createCmd.MarkFlagRequired("url") WebhooksCmd.AddCommand(listCmd) WebhooksCmd.AddCommand(createCmd) diff --git a/docs/assets/logo-full.png b/docs/assets/logo-full.png deleted file mode 100644 index 8f23275..0000000 Binary files a/docs/assets/logo-full.png and /dev/null differ diff --git a/docs/assets/logo-small.png b/docs/assets/logo-small.png deleted file mode 100644 index 9aa9add..0000000 Binary files a/docs/assets/logo-small.png and /dev/null differ diff --git a/docs/assets/logo.png b/docs/assets/logo.png deleted file mode 100644 index 7ce5fa2..0000000 Binary files a/docs/assets/logo.png and /dev/null differ diff --git a/docs/commands/apps.md b/docs/commands/apps.md deleted file mode 100644 index 5168472..0000000 --- a/docs/commands/apps.md +++ /dev/null @@ -1,174 +0,0 @@ -# Apps - -Manage applications within your RevenueCat project. Each app corresponds to a platform-specific distribution (App Store, Play Store, Stripe, etc.). - -## Available Commands - -| Command | Description | -|---|---| -| `rc apps list` | List all apps in the project | -| `rc apps get` | Get details for a specific app | -| `rc apps create` | Create a new app | -| `rc apps update` | Update an existing app | -| `rc apps delete` | Delete an app | -| `rc apps api-keys` | View API keys for an app | - ---- - -## `rc apps list` - -```bash -rc apps list -``` - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | -| `--limit` | Maximum number of results | `20` | -| `--starting-after` | Cursor for pagination | -- | -| `--all` | Fetch all pages automatically | `false` | - ---- - -## `rc apps get` - -Retrieve details for a single app. - -```bash -rc apps get --app-id app_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--app-id` | The app ID to retrieve | - ---- - -## `rc apps create` - -Create a new app in the current project. - -```bash -rc apps create --name "My iOS App" --type app_store --bundle-id com.example.myapp -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--name` | Display name for the app | -| `--type` | Store type | - -### App Types - -| Type | Description | -|---|---| -| `app_store` | Apple App Store | -| `play_store` | Google Play Store | -| `stripe` | Stripe | -| `amazon` | Amazon Appstore | -| `mac_app_store` | Mac App Store | -| `roku` | Roku Channel Store | -| `web` | Web | - -### Optional Flags - -| Flag | Description | -|---|---| -| `--bundle-id` | Bundle identifier (iOS/macOS) | -| `--package-name` | Package name (Android) | -| `--output` | Output format | - -### Examples - -=== "iOS App" - - ```bash - rc apps create \ - --name "My iOS App" \ - --type app_store \ - --bundle-id com.example.myapp - ``` - -=== "Android App" - - ```bash - rc apps create \ - --name "My Android App" \ - --type play_store \ - --package-name com.example.myapp - ``` - -=== "Stripe" - - ```bash - rc apps create \ - --name "Web Payments" \ - --type stripe - ``` - ---- - -## `rc apps update` - -Update an existing app's properties. - -```bash -rc apps update --app-id app_xxxxx --name "Renamed App" -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--app-id` | The app ID to update | - -### Optional Flags - -| Flag | Description | -|---|---| -| `--name` | New display name | -| `--output` | Output format | - ---- - -## `rc apps delete` - -Delete an app from the project. - -```bash -rc apps delete --app-id app_xxxxx --confirm -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--app-id` | The app ID to delete | -| `--confirm` | Skip confirmation prompt | - -!!! warning - Deleting an app is permanent. All associated data will be lost. - ---- - -## `rc apps api-keys` - -View the public and secret API keys for an app. - -```bash -rc apps api-keys --app-id app_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--app-id` | The app ID | - -!!! tip - Use `--output minimal` to get just the key values, useful for piping into scripts. diff --git a/docs/commands/audit-logs.md b/docs/commands/audit-logs.md deleted file mode 100644 index 42135a6..0000000 --- a/docs/commands/audit-logs.md +++ /dev/null @@ -1,59 +0,0 @@ -# Audit Logs - -View the audit log for your RevenueCat project. Audit logs track all administrative actions -- configuration changes, API key usage, team member activity, and more. - -## Available Commands - -| Command | Description | -|---|---| -| `rc audit-logs list` | List audit log entries | - ---- - -## `rc audit-logs list` - -Retrieve audit log entries with support for cursor-based pagination. - -```bash -rc audit-logs list -``` - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | -| `--limit` | Maximum number of results per page | `20` | -| `--starting-after` | Cursor for pagination (use the last entry's ID) | -- | -| `--all` | Fetch all pages automatically | `false` | - -### Example - -```bash -rc audit-logs list --limit 10 --output table -``` - -``` -ID ACTION ACTOR TIMESTAMP -aud_xxxxx entitlement.create user@example 2025-01-15T10:30:00Z -aud_yyyyy offering.update api_key_xxxx 2025-01-15T09:15:00Z -aud_zzzzz app.delete user@example 2025-01-14T18:45:00Z -``` - -### Paginating Through Results - -Audit logs can be large. Use cursor-based pagination to walk through results page by page: - -```bash -# First page -rc audit-logs list --limit 50 - -# Next page (use the last ID from the previous response) -rc audit-logs list --limit 50 --starting-after aud_last_id - -# Or fetch everything at once -rc audit-logs list --all --output csv > audit-log-export.csv -``` - -!!! tip - Export the full audit log to CSV for compliance reporting: `rc audit-logs list --all --output csv > audit.csv` diff --git a/docs/commands/auth.md b/docs/commands/auth.md deleted file mode 100644 index 97fa284..0000000 --- a/docs/commands/auth.md +++ /dev/null @@ -1,129 +0,0 @@ -# Auth - -Manage authentication profiles. Profiles store API keys locally and let you switch between different RevenueCat accounts or environments without re-entering credentials. - -## Available Commands - -| Command | Description | -|---|---| -| `rc auth login` | Create a new authentication profile | -| `rc auth switch` | Switch to a different profile | -| `rc auth list` | List all saved profiles | -| `rc auth current` | Show the currently active profile | -| `rc auth delete` | Delete a saved profile | - ---- - -## `rc auth login` - -Create and activate a new authentication profile. - -```bash -rc auth login --api-key sk_xxxxx --name production -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--api-key` | Your RevenueCat secret API key (starts with `sk_`) | -| `--name` | A name for this profile | - -### Optional Flags - -| Flag | Description | -|---|---| -| `--default-project` | Set a default project ID for this profile | - -### Examples - -=== "Basic" - - ```bash - rc auth login --api-key sk_xxxxx --name production - ``` - -=== "With Default Project" - - ```bash - rc auth login \ - --api-key sk_xxxxx \ - --name production \ - --default-project proj_xxxxx - ``` - -!!! note - API keys are stored in your system's credential store. They are never written to plain-text config files. - ---- - -## `rc auth switch` - -Switch the active profile. - -```bash -rc auth switch --name staging -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--name` | The profile name to switch to | - ---- - -## `rc auth list` - -List all saved authentication profiles. - -```bash -rc auth list -``` - -### Example Output - -``` -NAME PROJECT ACTIVE -production proj_xxxxx * -staging proj_yyyyy -personal -- -``` - ---- - -## `rc auth current` - -Display the currently active profile and its configuration. - -```bash -rc auth current -``` - -### Example Output - -``` -Profile: production -Project: proj_xxxxx -API Key: sk_...xxxxx (masked) -``` - ---- - -## `rc auth delete` - -Delete a saved authentication profile. - -```bash -rc auth delete --name old-profile --confirm -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--name` | The profile name to delete | -| `--confirm` | Skip confirmation prompt | - -!!! warning - This permanently removes the profile and its stored API key. If this is the active profile, you will need to switch to another profile or create a new one. diff --git a/docs/commands/customers.md b/docs/commands/customers.md deleted file mode 100644 index 3efc3d6..0000000 --- a/docs/commands/customers.md +++ /dev/null @@ -1,282 +0,0 @@ -# Customers - -Manage customers in your RevenueCat project. Customers represent the end users of your apps and hold subscriptions, purchases, entitlements, and attributes. - -## Available Commands - -| Command | Description | -|---|---| -| `rc customers list` | List all customers | -| `rc customers get` | Get a specific customer | -| `rc customers create` | Create a customer | -| `rc customers delete` | Delete a customer | -| `rc customers list-active-entitlements` | List a customer's active entitlements | -| `rc customers list-aliases` | List a customer's aliases | -| `rc customers list-attributes` | List a customer's attributes | -| `rc customers set-attributes` | Set attributes on a customer | -| `rc customers list-subscriptions` | List a customer's subscriptions | -| `rc customers list-purchases` | List a customer's purchases | -| `rc customers list-invoices` | List a customer's invoices | -| `rc customers transfer` | Transfer a customer to another ID | -| `rc customers grant-entitlement` | Grant a promotional entitlement | -| `rc customers revoke-entitlement` | Revoke a promotional entitlement | -| `rc customers assign-offering` | Assign a specific offering to a customer | - ---- - -## `rc customers list` - -```bash -rc customers list -``` - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | -| `--limit` | Maximum number of results | `20` | -| `--starting-after` | Cursor for pagination | -- | -| `--all` | Fetch all pages automatically | `false` | - ---- - -## `rc customers get` - -```bash -rc customers get --customer-id cust_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--customer-id` | The customer ID to retrieve | - ---- - -## `rc customers create` - -Create a new customer with a specified ID. - -```bash -rc customers create --customer-id my_custom_id -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--customer-id` | The ID for the new customer | - ---- - -## `rc customers delete` - -```bash -rc customers delete --customer-id cust_xxxxx --confirm -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--customer-id` | The customer ID to delete | -| `--confirm` | Skip confirmation prompt | - -!!! warning - Deleting a customer is permanent and removes all associated data including subscription history, attributes, and entitlements. - ---- - -## `rc customers list-active-entitlements` - -List entitlements currently active for a customer. - -```bash -rc customers list-active-entitlements --customer-id cust_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--customer-id` | The customer ID | - ---- - -## `rc customers list-aliases` - -List all aliases associated with a customer. - -```bash -rc customers list-aliases --customer-id cust_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--customer-id` | The customer ID | - ---- - -## `rc customers list-attributes` - -List all custom attributes set on a customer. - -```bash -rc customers list-attributes --customer-id cust_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--customer-id` | The customer ID | - ---- - -## `rc customers set-attributes` - -Set custom attributes on a customer. Attributes are key-value pairs useful for segmentation and analytics. - -```bash -rc customers set-attributes \ - --customer-id cust_xxxxx \ - --attributes '{"tier": "vip", "region": "us-west"}' -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--customer-id` | The customer ID | -| `--attributes` | JSON object of key-value pairs | - -!!! note - Setting an attribute key to an empty string (`""`) deletes that attribute. - ---- - -## `rc customers list-subscriptions` - -```bash -rc customers list-subscriptions --customer-id cust_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--customer-id` | The customer ID | - ---- - -## `rc customers list-purchases` - -```bash -rc customers list-purchases --customer-id cust_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--customer-id` | The customer ID | - ---- - -## `rc customers list-invoices` - -```bash -rc customers list-invoices --customer-id cust_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--customer-id` | The customer ID | - ---- - -## `rc customers transfer` - -Transfer a customer's data to a different customer ID. - -```bash -rc customers transfer \ - --customer-id cust_xxxxx \ - --target-id cust_yyyyy -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--customer-id` | The source customer ID | -| `--target-id` | The destination customer ID | - -!!! warning - Transfer merges subscription and purchase history into the target customer. The source customer will be left empty. - ---- - -## `rc customers grant-entitlement` - -Grant a promotional entitlement to a customer. This gives access without requiring a purchase. - -```bash -rc customers grant-entitlement \ - --customer-id cust_xxxxx \ - --entitlement-id entl_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--customer-id` | The customer ID | -| `--entitlement-id` | The entitlement ID to grant | - ---- - -## `rc customers revoke-entitlement` - -Revoke a previously granted promotional entitlement. - -```bash -rc customers revoke-entitlement \ - --customer-id cust_xxxxx \ - --entitlement-id entl_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--customer-id` | The customer ID | -| `--entitlement-id` | The entitlement ID to revoke | - ---- - -## `rc customers assign-offering` - -Override the offering shown to a specific customer. This is useful for A/B testing or granting special pricing. - -```bash -rc customers assign-offering \ - --customer-id cust_xxxxx \ - --offering-id ofr_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--customer-id` | The customer ID | -| `--offering-id` | The offering ID to assign | - -!!! tip - To revert a customer to the default offering, assign the offering currently marked as `is_current: true`. diff --git a/docs/commands/entitlements.md b/docs/commands/entitlements.md deleted file mode 100644 index 5f9d60d..0000000 --- a/docs/commands/entitlements.md +++ /dev/null @@ -1,157 +0,0 @@ -# Entitlements - -Manage entitlements in your RevenueCat project. Entitlements represent levels of access that a customer can "unlock" through purchasing products. - -## Available Commands - -| Command | Description | -|---|---| -| `rc entitlements list` | List all entitlements | -| `rc entitlements get` | Get a specific entitlement | -| `rc entitlements create` | Create a new entitlement | -| `rc entitlements update` | Update an entitlement | -| `rc entitlements delete` | Delete an entitlement | -| `rc entitlements list-products` | List products attached to an entitlement | -| `rc entitlements attach-products` | Attach products to an entitlement | -| `rc entitlements detach-products` | Detach products from an entitlement | - ---- - -## `rc entitlements list` - -```bash -rc entitlements list -``` - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | -| `--limit` | Maximum number of results | `20` | -| `--starting-after` | Cursor for pagination | -- | -| `--all` | Fetch all pages automatically | `false` | - ---- - -## `rc entitlements get` - -```bash -rc entitlements get --entitlement-id entl_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--entitlement-id` | The entitlement ID to retrieve | - ---- - -## `rc entitlements create` - -```bash -rc entitlements create --lookup-key premium --display-name "Premium Access" -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--lookup-key` | Unique lookup key for the entitlement | -| `--display-name` | Human-readable display name | - ---- - -## `rc entitlements update` - -```bash -rc entitlements update --entitlement-id entl_xxxxx --display-name "Pro Access" -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--entitlement-id` | The entitlement ID to update | - -### Optional Flags - -| Flag | Description | -|---|---| -| `--display-name` | New display name | - ---- - -## `rc entitlements delete` - -```bash -rc entitlements delete --entitlement-id entl_xxxxx --confirm -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--entitlement-id` | The entitlement ID to delete | -| `--confirm` | Skip confirmation prompt | - -!!! warning - Deleting an entitlement removes it from all offerings. Existing customer grants are not revoked. - ---- - -## `rc entitlements list-products` - -List all products attached to an entitlement. - -```bash -rc entitlements list-products --entitlement-id entl_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--entitlement-id` | The entitlement ID | - ---- - -## `rc entitlements attach-products` - -Attach one or more products to an entitlement. When a customer purchases any attached product, they receive this entitlement. - -```bash -rc entitlements attach-products \ - --entitlement-id entl_xxxxx \ - --product-ids prod_aaaaa,prod_bbbbb -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--entitlement-id` | The entitlement ID | -| `--product-ids` | Comma-separated list of product IDs to attach | - -!!! tip - You can attach products from different apps to the same entitlement. This is how cross-platform access works in RevenueCat. - ---- - -## `rc entitlements detach-products` - -Detach one or more products from an entitlement. - -```bash -rc entitlements detach-products \ - --entitlement-id entl_xxxxx \ - --product-ids prod_aaaaa -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--entitlement-id` | The entitlement ID | -| `--product-ids` | Comma-separated list of product IDs to detach | diff --git a/docs/commands/metrics.md b/docs/commands/metrics.md deleted file mode 100644 index f2c06f6..0000000 --- a/docs/commands/metrics.md +++ /dev/null @@ -1,78 +0,0 @@ -# Metrics - -View key subscription metrics for your RevenueCat project. Metrics provide a real-time snapshot of your subscription business health. - -## Available Commands - -| Command | Description | -|---|---| -| `rc metrics overview` | Display key subscription metrics | - ---- - -## `rc metrics overview` - -Retrieve a high-level overview of your project's subscription metrics. - -```bash -rc metrics overview -``` - -### Metrics Returned - -| Metric | Description | -|---|---| -| **MRR** | Monthly Recurring Revenue | -| **Active Subscribers** | Number of customers with active paid subscriptions | -| **Active Trials** | Number of customers currently in a free trial | -| **Revenue** | Total revenue for the current period | - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | - -### Examples - -=== "Table Output" - - ```bash - rc metrics overview --output table - ``` - - ``` - METRIC VALUE - MRR $12,450.00 - Active Subscribers 1,823 - Active Trials 342 - Revenue $14,200.00 - ``` - -=== "JSON Output" - - ```bash - rc metrics overview --output json - ``` - - ```json - { - "mrr": 12450.00, - "active_subscribers": 1823, - "active_trials": 342, - "revenue": 14200.00 - } - ``` - -=== "Minimal Output" - - ```bash - rc metrics overview --output minimal - ``` - - ``` - 12450.00 1823 342 14200.00 - ``` - -!!! tip - Combine with `watch` for a live dashboard: `watch -n 60 rc metrics overview --output table` diff --git a/docs/commands/offerings.md b/docs/commands/offerings.md deleted file mode 100644 index bbad736..0000000 --- a/docs/commands/offerings.md +++ /dev/null @@ -1,134 +0,0 @@ -# Offerings - -Manage offerings in your RevenueCat project. Offerings are the selection of products that are presented to a customer on your paywall. Each project can have multiple offerings, with one marked as "current." - -## Available Commands - -| Command | Description | -|---|---| -| `rc offerings list` | List all offerings | -| `rc offerings get` | Get a specific offering | -| `rc offerings create` | Create a new offering | -| `rc offerings update` | Update an offering | -| `rc offerings delete` | Delete an offering | - ---- - -## `rc offerings list` - -```bash -rc offerings list -``` - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | -| `--limit` | Maximum number of results | `20` | -| `--starting-after` | Cursor for pagination | -- | -| `--all` | Fetch all pages automatically | `false` | - -### Example - -```bash -rc offerings list --output table -``` - -``` -ID LOOKUP KEY DISPLAY NAME IS CURRENT -ofr_xxxxx default Default Offering true -ofr_yyyyy experiment_a Experiment A false -``` - ---- - -## `rc offerings get` - -```bash -rc offerings get --offering-id ofr_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--offering-id` | The offering ID to retrieve | - ---- - -## `rc offerings create` - -```bash -rc offerings create \ - --lookup-key default \ - --display-name "Default Offering" -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--lookup-key` | Unique lookup key for the offering | -| `--display-name` | Human-readable display name | - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--is-current` | Set as the current offering | `false` | -| `--metadata` | JSON metadata string | -- | -| `--output` | Output format | `json` | - -### Example - -```bash -rc offerings create \ - --lookup-key holiday_sale \ - --display-name "Holiday Sale" \ - --metadata '{"discount": "30%"}' \ - --is-current false -``` - ---- - -## `rc offerings update` - -```bash -rc offerings update --offering-id ofr_xxxxx --display-name "Updated Name" -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--offering-id` | The offering ID to update | - -### Optional Flags - -| Flag | Description | -|---|---| -| `--display-name` | New display name | -| `--is-current` | Set or unset as current offering | -| `--metadata` | Updated JSON metadata | - -!!! tip - Setting `--is-current true` on an offering automatically unsets the previously current offering. - ---- - -## `rc offerings delete` - -```bash -rc offerings delete --offering-id ofr_xxxxx --confirm -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--offering-id` | The offering ID to delete | -| `--confirm` | Skip confirmation prompt | - -!!! warning - Deleting an offering also removes all its packages. Make sure no active paywalls reference this offering. diff --git a/docs/commands/packages.md b/docs/commands/packages.md deleted file mode 100644 index 3ba5be7..0000000 --- a/docs/commands/packages.md +++ /dev/null @@ -1,188 +0,0 @@ -# Packages - -Manage packages within offerings. A package is a group of equivalent products across platforms within a single offering. For example, a "monthly" package might contain the iOS and Android versions of the same subscription. - -## Available Commands - -| Command | Description | -|---|---| -| `rc packages list` | List all packages in an offering | -| `rc packages get` | Get a specific package | -| `rc packages create` | Create a new package | -| `rc packages update` | Update a package | -| `rc packages delete` | Delete a package | -| `rc packages list-products` | List products attached to a package | -| `rc packages attach-products` | Attach products to a package | -| `rc packages detach-products` | Detach products from a package | - ---- - -## `rc packages list` - -List all packages in a specific offering. - -```bash -rc packages list --offering-id ofr_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--offering-id` | The offering ID to list packages for | - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | -| `--limit` | Maximum number of results | `20` | -| `--starting-after` | Cursor for pagination | -- | -| `--all` | Fetch all pages automatically | `false` | - ---- - -## `rc packages get` - -```bash -rc packages get --offering-id ofr_xxxxx --package-id pkg_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--offering-id` | The offering ID | -| `--package-id` | The package ID to retrieve | - ---- - -## `rc packages create` - -```bash -rc packages create \ - --offering-id ofr_xxxxx \ - --lookup-key monthly \ - --display-name "Monthly Plan" -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--offering-id` | The offering to create the package in | -| `--lookup-key` | Unique lookup key within the offering | -| `--display-name` | Human-readable display name | - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | - ---- - -## `rc packages update` - -```bash -rc packages update \ - --offering-id ofr_xxxxx \ - --package-id pkg_xxxxx \ - --display-name "Premium Monthly" -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--offering-id` | The offering ID | -| `--package-id` | The package ID to update | - -### Optional Flags - -| Flag | Description | -|---|---| -| `--display-name` | New display name | - ---- - -## `rc packages delete` - -```bash -rc packages delete \ - --offering-id ofr_xxxxx \ - --package-id pkg_xxxxx \ - --confirm -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--offering-id` | The offering ID | -| `--package-id` | The package ID to delete | -| `--confirm` | Skip confirmation prompt | - ---- - -## `rc packages list-products` - -List all products attached to a package. - -```bash -rc packages list-products \ - --offering-id ofr_xxxxx \ - --package-id pkg_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--offering-id` | The offering ID | -| `--package-id` | The package ID | - ---- - -## `rc packages attach-products` - -Attach products to a package. This defines which store products are included when a customer sees this package. - -```bash -rc packages attach-products \ - --offering-id ofr_xxxxx \ - --package-id pkg_xxxxx \ - --product-ids prod_aaaaa,prod_bbbbb -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--offering-id` | The offering ID | -| `--package-id` | The package ID | -| `--product-ids` | Comma-separated list of product IDs to attach | - -!!! tip - Attach one product per platform to a package. For example, attach both the iOS `app_store` product and the Android `play_store` product to the same "monthly" package for cross-platform parity. - ---- - -## `rc packages detach-products` - -Detach products from a package. - -```bash -rc packages detach-products \ - --offering-id ofr_xxxxx \ - --package-id pkg_xxxxx \ - --product-ids prod_aaaaa -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--offering-id` | The offering ID | -| `--package-id` | The package ID | -| `--product-ids` | Comma-separated list of product IDs to detach | diff --git a/docs/commands/paywalls.md b/docs/commands/paywalls.md deleted file mode 100644 index b8646a2..0000000 --- a/docs/commands/paywalls.md +++ /dev/null @@ -1,83 +0,0 @@ -# Paywalls - -Manage paywalls in your RevenueCat project. Paywalls define the UI presentation layer for your offerings and are configured through the RevenueCat dashboard or API. - -## Available Commands - -| Command | Description | -|---|---| -| `rc paywalls list` | List all paywalls | -| `rc paywalls get` | Get a specific paywall | -| `rc paywalls create` | Create a new paywall | -| `rc paywalls delete` | Delete a paywall | - ---- - -## `rc paywalls list` - -```bash -rc paywalls list -``` - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | -| `--limit` | Maximum number of results | `20` | -| `--starting-after` | Cursor for pagination | -- | -| `--all` | Fetch all pages automatically | `false` | - ---- - -## `rc paywalls get` - -```bash -rc paywalls get --paywall-id pw_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--paywall-id` | The paywall ID to retrieve | - ---- - -## `rc paywalls create` - -Create a new paywall and associate it with an offering. - -```bash -rc paywalls create --offering-id ofr_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--offering-id` | The offering to attach the paywall to | - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | - ---- - -## `rc paywalls delete` - -```bash -rc paywalls delete --paywall-id pw_xxxxx --confirm -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--paywall-id` | The paywall ID to delete | -| `--confirm` | Skip confirmation prompt | - -!!! warning - Deleting a paywall removes it from its associated offering. Customers currently viewing this paywall will fall back to the default presentation. diff --git a/docs/commands/products.md b/docs/commands/products.md deleted file mode 100644 index e38a7a7..0000000 --- a/docs/commands/products.md +++ /dev/null @@ -1,127 +0,0 @@ -# Products - -Manage products within your RevenueCat project. Products map to store-specific identifiers and define what your customers can purchase. - -## Available Commands - -| Command | Description | -|---|---| -| `rc products list` | List all products | -| `rc products get` | Get a specific product | -| `rc products create` | Create a new product | -| `rc products delete` | Delete a product | - ---- - -## `rc products list` - -List all products in the current project. - -```bash -rc products list -``` - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--app-id` | Filter products by app | -- | -| `--output` | Output format | `json` | -| `--limit` | Maximum number of results | `20` | -| `--starting-after` | Cursor for pagination | -- | -| `--all` | Fetch all pages automatically | `false` | - -### Example - -```bash -rc products list --app-id app_xxxxx --output table -``` - -``` -ID STORE IDENTIFIER TYPE -prod_xxxxx com.app.monthly subscription -prod_yyyyy com.app.lifetime one_time -``` - ---- - -## `rc products get` - -Retrieve details for a specific product. - -```bash -rc products get --product-id prod_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--product-id` | The product ID to retrieve | - ---- - -## `rc products create` - -Create a new product. - -```bash -rc products create \ - --app-id app_xxxxx \ - --store-identifier com.example.premium.monthly \ - --type subscription -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--app-id` | The app this product belongs to | -| `--store-identifier` | The product identifier in the store | -| `--type` | Product type: `subscription` or `one_time` | - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | - -### Examples - -=== "Subscription" - - ```bash - rc products create \ - --app-id app_xxxxx \ - --store-identifier com.example.premium.monthly \ - --type subscription - ``` - -=== "One-Time Purchase" - - ```bash - rc products create \ - --app-id app_xxxxx \ - --store-identifier com.example.lifetime \ - --type one_time - ``` - ---- - -## `rc products delete` - -Delete a product from the project. - -```bash -rc products delete --product-id prod_xxxxx --confirm -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--product-id` | The product ID to delete | -| `--confirm` | Skip confirmation prompt | - -!!! warning - Deleting a product detaches it from all entitlements and packages. Active subscriptions are not affected. diff --git a/docs/commands/projects.md b/docs/commands/projects.md deleted file mode 100644 index 25da9ec..0000000 --- a/docs/commands/projects.md +++ /dev/null @@ -1,69 +0,0 @@ -# Projects - -Manage RevenueCat projects. A project is the top-level container for your apps, products, and entitlements. - -## Available Commands - -| Command | Description | -|---|---| -| `rc projects list` | List all projects accessible with your API key | -| `rc projects create` | Create a new project | - ---- - -## `rc projects list` - -List all projects associated with the current API key. - -```bash -rc projects list -``` - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format (`json`, `pretty`, `table`, `csv`, `tsv`, `yaml`, `minimal`) | `json` | -| `--limit` | Maximum number of results | `20` | -| `--starting-after` | Cursor for pagination | -- | -| `--all` | Fetch all pages automatically | `false` | - -### Example - -```bash -rc projects list --output table -``` - -``` -ID NAME -proj_xxxxx Production -proj_yyyyy Staging -``` - ---- - -## `rc projects create` - -Create a new RevenueCat project. - -```bash -rc projects create --name "My New Project" -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--name` | Name for the new project | - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | - -### Example - -```bash -rc projects create --name "Staging Environment" --output pretty -``` diff --git a/docs/commands/purchases.md b/docs/commands/purchases.md deleted file mode 100644 index 82a3c8d..0000000 --- a/docs/commands/purchases.md +++ /dev/null @@ -1,69 +0,0 @@ -# Purchases - -View and manage one-time purchases. Purchases represent non-recurring transactions such as lifetime unlocks or consumable items. - -## Available Commands - -| Command | Description | -|---|---| -| `rc purchases get` | Get details for a specific purchase | -| `rc purchases list-entitlements` | List entitlements granted by a purchase | -| `rc purchases refund` | Refund a purchase | - ---- - -## `rc purchases get` - -Retrieve full details for a purchase. - -```bash -rc purchases get --purchase-id pur_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--purchase-id` | The purchase ID to retrieve | - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | - ---- - -## `rc purchases list-entitlements` - -List all entitlements granted by a specific purchase. - -```bash -rc purchases list-entitlements --purchase-id pur_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--purchase-id` | The purchase ID | - ---- - -## `rc purchases refund` - -Issue a refund for a one-time purchase. This revokes any entitlements granted by the purchase. - -```bash -rc purchases refund --purchase-id pur_xxxxx --confirm -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--purchase-id` | The purchase ID to refund | -| `--confirm` | Skip confirmation prompt | - -!!! warning - Refunding a purchase immediately revokes entitlements and issues a refund through the original payment processor. This cannot be undone. diff --git a/docs/commands/subscriptions.md b/docs/commands/subscriptions.md deleted file mode 100644 index dcade06..0000000 --- a/docs/commands/subscriptions.md +++ /dev/null @@ -1,90 +0,0 @@ -# Subscriptions - -View and manage subscriptions. Subscriptions represent recurring purchases tied to a customer and product. - -## Available Commands - -| Command | Description | -|---|---| -| `rc subscriptions get` | Get details for a specific subscription | -| `rc subscriptions list-entitlements` | List entitlements granted by a subscription | -| `rc subscriptions cancel` | Cancel a subscription | -| `rc subscriptions refund` | Refund a subscription | - ---- - -## `rc subscriptions get` - -Retrieve full details for a subscription including its status, renewal date, and associated product. - -```bash -rc subscriptions get --subscription-id sub_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--subscription-id` | The subscription ID to retrieve | - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | - ---- - -## `rc subscriptions list-entitlements` - -List all entitlements granted by a specific subscription. - -```bash -rc subscriptions list-entitlements --subscription-id sub_xxxxx -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--subscription-id` | The subscription ID | - ---- - -## `rc subscriptions cancel` - -Cancel an active subscription. The customer retains access until the end of the current billing period. - -```bash -rc subscriptions cancel --subscription-id sub_xxxxx --confirm -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--subscription-id` | The subscription ID to cancel | -| `--confirm` | Skip confirmation prompt | - -!!! note - Cancellation takes effect at the end of the current billing period. The customer is not immediately revoked. - ---- - -## `rc subscriptions refund` - -Issue a refund for a subscription. This revokes access immediately. - -```bash -rc subscriptions refund --subscription-id sub_xxxxx --confirm -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--subscription-id` | The subscription ID to refund | -| `--confirm` | Skip confirmation prompt | - -!!! warning - Refunding a subscription immediately revokes the customer's access and issues a refund through the original payment processor. diff --git a/docs/commands/webhooks.md b/docs/commands/webhooks.md deleted file mode 100644 index 009100a..0000000 --- a/docs/commands/webhooks.md +++ /dev/null @@ -1,72 +0,0 @@ -# Webhooks - -Manage webhook endpoints for your RevenueCat project. Webhooks deliver real-time event notifications (purchases, renewals, cancellations, etc.) to your server. - -## Available Commands - -| Command | Description | -|---|---| -| `rc webhooks list` | List all configured webhooks | -| `rc webhooks create` | Create a new webhook endpoint | - ---- - -## `rc webhooks list` - -```bash -rc webhooks list -``` - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | -| `--limit` | Maximum number of results | `20` | -| `--starting-after` | Cursor for pagination | -- | -| `--all` | Fetch all pages automatically | `false` | - -### Example - -```bash -rc webhooks list --output table -``` - -``` -ID URL -wh_xxxxx https://api.example.com/webhooks/revenuecat -wh_yyyyy https://staging.example.com/webhooks/rc -``` - ---- - -## `rc webhooks create` - -Register a new webhook endpoint. - -```bash -rc webhooks create --url https://api.example.com/webhooks/revenuecat -``` - -### Required Flags - -| Flag | Description | -|---|---| -| `--url` | The HTTPS endpoint URL to receive webhook events | - -### Optional Flags - -| Flag | Description | Default | -|---|---|---| -| `--output` | Output format | `json` | - -!!! note - Webhook URLs must use HTTPS. RevenueCat will send a test event to verify the endpoint is reachable before activating it. - -### Example - -```bash -rc webhooks create \ - --url https://api.example.com/webhooks/revenuecat \ - --output pretty -``` diff --git a/docs/getting-started/configuration.md b/docs/getting-started/configuration.md deleted file mode 100644 index 4fcd541..0000000 --- a/docs/getting-started/configuration.md +++ /dev/null @@ -1,103 +0,0 @@ -# Configuration - -RevenueCat CLI supports multiple authentication profiles, project-level defaults, and environment variable overrides. This page covers all configuration options. - -## Authentication Profiles - -Profiles let you store multiple API keys and switch between them. This is useful when managing staging and production environments, or multiple RevenueCat accounts. - -### Create a Profile - -```bash -rc auth login --api-key sk_xxxxx --name production -``` - -You can optionally bind a default project to a profile: - -```bash -rc auth login --api-key sk_xxxxx --name production --default-project proj_xxxxx -``` - -### Switch Profiles - -```bash -rc auth switch --name staging -``` - -### List All Profiles - -```bash -rc auth list -``` - -### View Current Profile - -```bash -rc auth current -``` - -### Delete a Profile - -```bash -rc auth delete --name old-profile --confirm -``` - -!!! warning - Deleting a profile removes its stored API key permanently. This action cannot be undone. - ---- - -## Project Configuration - -### Initialize a Project - -Bind a default project to the current directory: - -```bash -rc init --project proj_xxxxx -``` - -This creates a `.rc.yaml` file in the current directory. - -### `.rc.yaml` File Format - -```yaml -project: proj_xxxxx -``` - -When a `.rc.yaml` file is present, all commands automatically use that project ID. You can override it per-command with the `--project` flag. - -!!! tip - Commit `.rc.yaml` to your repository so your team shares the same project configuration. - ---- - -## Environment Variables - -Environment variables override profile and file-based configuration. They are especially useful in CI/CD pipelines. - -| Variable | Description | Example | -|---|---|---| -| `RC_API_KEY` | API secret key (overrides active profile) | `sk_xxxxx` | -| `RC_PROJECT` | Default project ID | `proj_xxxxx` | -| `RC_PROFILE` | Active profile name | `production` | -| `RC_OUTPUT` | Default output format | `json`, `table`, `csv` | -| `RC_DEBUG` | Enable debug logging | `true` | -| `RC_TIMEOUT` | HTTP request timeout | `30s` | - -### Precedence Order - -Configuration is resolved in this order (highest priority first): - -1. Command-line flags (`--project`, `--output`, etc.) -2. Environment variables (`RC_PROJECT`, `RC_OUTPUT`, etc.) -3. Local `.rc.yaml` file -4. Active auth profile defaults -5. Built-in defaults - -!!! note - Flags always win. If you pass `--project proj_yyy` on the command line, it overrides everything else. - -## Next Steps - -Head to the [Quick Start](quickstart.md) to run your first commands. diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md deleted file mode 100644 index b145243..0000000 --- a/docs/getting-started/installation.md +++ /dev/null @@ -1,68 +0,0 @@ -# Installation - -## Homebrew (Recommended) - -The fastest way to install RevenueCat CLI on macOS or Linux: - -```bash -brew tap AndroidPoet/tap -brew install revenuecat-cli -``` - -To upgrade to the latest version: - -```bash -brew upgrade revenuecat-cli -``` - -## Direct Download - -Download pre-built binaries from the [GitHub Releases](https://github.com/AndroidPoet/revenuecat-cli/releases) page. - -=== "macOS (Apple Silicon)" - - ```bash - curl -LO https://github.com/AndroidPoet/revenuecat-cli/releases/latest/download/revenuecat-cli_darwin_arm64.tar.gz - tar -xzf revenuecat-cli_darwin_arm64.tar.gz - sudo mv rc /usr/local/bin/ - ``` - -=== "macOS (Intel)" - - ```bash - curl -LO https://github.com/AndroidPoet/revenuecat-cli/releases/latest/download/revenuecat-cli_darwin_amd64.tar.gz - tar -xzf revenuecat-cli_darwin_amd64.tar.gz - sudo mv rc /usr/local/bin/ - ``` - -=== "Linux (amd64)" - - ```bash - curl -LO https://github.com/AndroidPoet/revenuecat-cli/releases/latest/download/revenuecat-cli_linux_amd64.tar.gz - tar -xzf revenuecat-cli_linux_amd64.tar.gz - sudo mv rc /usr/local/bin/ - ``` - -=== "Linux (arm64)" - - ```bash - curl -LO https://github.com/AndroidPoet/revenuecat-cli/releases/latest/download/revenuecat-cli_linux_arm64.tar.gz - tar -xzf revenuecat-cli_linux_arm64.tar.gz - sudo mv rc /usr/local/bin/ - ``` - -## Verify Installation - -```bash -rc version -``` - -You should see output like: - -``` -revenuecat-cli version 0.1.0 -``` - -## Next Steps - -Once installed, proceed to [Configuration](configuration.md) to set up your authentication profile. diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md deleted file mode 100644 index f9f6541..0000000 --- a/docs/getting-started/quickstart.md +++ /dev/null @@ -1,139 +0,0 @@ -# Quick Start - -Get up and running with RevenueCat CLI in under a minute. - -## Step 1: Authenticate - -```bash -rc auth login --api-key sk_xxxxx --name myproject -``` - -This stores your API key in a named profile. You can create multiple profiles for different environments. - -## Step 2: Set Your Project - -```bash -rc init --project proj_xxxxx -``` - -This writes a `.rc.yaml` file in the current directory so all subsequent commands know which project to target. - -## Step 3: Verify - -```bash -rc doctor -``` - -The doctor command validates your authentication, project configuration, and API connectivity. A successful check looks like: - -``` -Authentication: OK -Project: OK (proj_xxxxx) -API Connection: OK (latency: 120ms) -``` - ---- - -## Your First Commands - -### List Your Apps - -```bash -rc apps list -``` - -### List Products in Table Format - -```bash -rc products list --output table -``` - -### Get a Specific Customer - -```bash -rc customers get --customer-id cust_xxxxx --output pretty -``` - -### View Metrics Overview - -```bash -rc metrics overview --output table -``` - ---- - -## Output Format Examples - -RevenueCat CLI supports 7 output formats. Use the `--output` flag to switch between them. - -=== "JSON (default)" - - ```bash - rc apps list --output json - ``` - - ```json - { - "items": [ - { - "id": "app_xxxxx", - "name": "My App", - "type": "app_store" - } - ] - } - ``` - -=== "Table" - - ```bash - rc apps list --output table - ``` - - ``` - ID NAME TYPE - app_xxxxx My App app_store - app_yyyyy Web App stripe - ``` - -=== "CSV" - - ```bash - rc apps list --output csv - ``` - - ``` - id,name,type - app_xxxxx,My App,app_store - app_yyyyy,Web App,stripe - ``` - ---- - -## Common Workflows - -### Pipe to jq - -```bash -rc products list --output json | jq '.items[] | {id, identifier: .store_identifier}' -``` - -### Export to CSV - -```bash -rc customers list --all --output csv > customers.csv -``` - -### Quick Lookup - -```bash -rc entitlements get --entitlement-id entl_xxxxx --output minimal -``` - ---- - -## What's Next? - -- Browse the [Commands](../commands/projects.md) reference for all 65+ commands -- Learn about [Output Formats](../reference/output-formats.md) in detail -- Set up [Shell Completion](../reference/shell-completion.md) for tab autocompletion diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index e2a2e37..0000000 --- a/docs/index.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -hide: - - navigation - - toc ---- - -
- -![RevenueCat CLI](assets/logo-full.png){ width="500" } - -
- -
- -**Your AI-powered subscription management companion for the command line.** - -Manage your entire RevenueCat project without leaving the terminal. From products and entitlements to customers and metrics -- everything at your fingertips. - -
- ---- - -## Why RevenueCat CLI? - -| Feature | Details | -|---|---| -| **65+ Commands** | Full coverage of the RevenueCat REST API v2 | -| **14 Resource Groups** | Projects, Apps, Products, Entitlements, Offerings, Packages, Customers, Subscriptions, Purchases, Paywalls, Metrics, Webhooks, Audit Logs, Auth | -| **7 Output Formats** | JSON, Pretty JSON, Table, CSV, TSV, YAML, Minimal | -| **Cursor-Based Pagination** | Efficiently traverse large datasets with `--limit`, `--starting-after`, and `--all` | -| **Multiple Auth Profiles** | Switch between accounts and projects seamlessly | -| **Shell Completion** | Bash, Zsh, Fish, and PowerShell support | - ---- - -## Quick Install - -```bash -brew tap AndroidPoet/tap && brew install revenuecat-cli -``` - -Verify the installation: - -```bash -rc version -``` - ---- - -## Get Started in 60 Seconds - -```bash -# 1. Authenticate -rc auth login --api-key sk_xxxxx --name production - -# 2. Set your project -rc init --project proj_xxxxx - -# 3. Verify everything works -rc doctor - -# 4. Start managing -rc apps list -rc products list --output table -``` - ---- - -## What's Next? - -
- -- [**Installation**](getting-started/installation.md) -- Install via Homebrew or direct download -- [**Configuration**](getting-started/configuration.md) -- Set up auth profiles and project defaults -- [**Quick Start**](getting-started/quickstart.md) -- Your first commands in under a minute -- [**Commands**](commands/projects.md) -- Browse all 65+ commands across 14 resource groups - -
diff --git a/docs/reference/environment-variables.md b/docs/reference/environment-variables.md deleted file mode 100644 index 238b3c1..0000000 --- a/docs/reference/environment-variables.md +++ /dev/null @@ -1,67 +0,0 @@ -# Environment Variables - -RevenueCat CLI can be configured entirely through environment variables. This is especially useful for CI/CD pipelines, Docker containers, and automated workflows. - -## Available Variables - -| Variable | Description | Example | Default | -|---|---|---|---| -| `RC_API_KEY` | Secret API key (overrides active profile) | `sk_xxxxx` | -- | -| `RC_PROJECT` | Default project ID | `proj_xxxxx` | -- | -| `RC_PROFILE` | Active auth profile name | `production` | First created profile | -| `RC_OUTPUT` | Default output format | `table` | `json` | -| `RC_DEBUG` | Enable debug logging (shows HTTP requests/responses) | `true` | `false` | -| `RC_TIMEOUT` | HTTP request timeout duration | `30s` | `10s` | - ---- - -## Precedence - -Environment variables sit in the middle of the configuration hierarchy: - -1. **Command-line flags** (highest priority) -2. **Environment variables** -3. **Local `.rc.yaml` file** -4. **Active auth profile** -5. **Built-in defaults** (lowest priority) - -### Example - -```bash -export RC_OUTPUT=yaml - -# Uses YAML (from env var) -rc apps list - -# Uses table (flag overrides env var) -rc apps list --output table -``` - ---- - -## Usage Examples - -### Shell Profile - -Add to `~/.bashrc` or `~/.zshrc` for persistent defaults: - -```bash -export RC_PROFILE="production" -export RC_OUTPUT="table" -``` - ---- - -## Debugging - -Enable debug mode to see full HTTP request and response details: - -```bash -export RC_DEBUG=true -rc apps list -``` - -This outputs request URLs, headers, response status codes, and timing information. Useful for troubleshooting API errors. - -!!! warning - Debug mode prints API responses to stderr, which may include sensitive data. Do not enable it in production logs. diff --git a/docs/reference/output-formats.md b/docs/reference/output-formats.md deleted file mode 100644 index 9d7fea1..0000000 --- a/docs/reference/output-formats.md +++ /dev/null @@ -1,157 +0,0 @@ -# Output Formats - -RevenueCat CLI supports 7 output formats. Use the `--output` flag (or the `RC_OUTPUT` environment variable) to switch between them. - -```bash -rc --output -``` - ---- - -## Available Formats - -| Format | Flag Value | Best For | -|---|---|---| -| JSON | `json` | Piping to `jq`, API integration, scripting | -| Pretty JSON | `pretty` | Human-readable inspection | -| Table | `table` | Quick visual overview in the terminal | -| CSV | `csv` | Spreadsheet import, data analysis | -| TSV | `tsv` | Tab-separated processing, clipboard pasting | -| YAML | `yaml` | Configuration files, readability | -| Minimal | `minimal` | Extracting single values for shell scripts | - ---- - -## Format Examples - -All examples use `rc apps list` with two apps in the project. - -### JSON (default) - -```bash -rc apps list --output json -``` - -```json -{ - "items": [ - { - "id": "app_xxxxx", - "name": "My iOS App", - "type": "app_store" - }, - { - "id": "app_yyyyy", - "name": "My Android App", - "type": "play_store" - } - ], - "next_page": null -} -``` - -### Pretty JSON - -```bash -rc apps list --output pretty -``` - -Identical structure to JSON but with syntax highlighting and indentation optimized for terminal readability. - -### Table - -```bash -rc apps list --output table -``` - -``` -ID NAME TYPE -app_xxxxx My iOS App app_store -app_yyyyy My Android App play_store -``` - -### CSV - -```bash -rc apps list --output csv -``` - -``` -id,name,type -app_xxxxx,My iOS App,app_store -app_yyyyy,My Android App,play_store -``` - -### TSV - -```bash -rc apps list --output tsv -``` - -``` -id name type -app_xxxxx My iOS App app_store -app_yyyyy My Android App play_store -``` - -### YAML - -```bash -rc apps list --output yaml -``` - -```yaml -items: - - id: app_xxxxx - name: My iOS App - type: app_store - - id: app_yyyyy - name: My Android App - type: play_store -next_page: null -``` - -### Minimal - -```bash -rc apps list --output minimal -``` - -``` -app_xxxxx My iOS App app_store -app_yyyyy My Android App play_store -``` - -!!! tip - Minimal output is ideal for shell scripts. Combine with `awk` to extract specific fields: - - ```bash - rc apps list --output minimal | awk '{print $1}' - ``` - ---- - -## Setting a Default Format - -### Per-session - -```bash -export RC_OUTPUT=table -rc apps list # uses table format -rc products list # also uses table format -``` - -### Per-profile - -```bash -rc auth login --api-key sk_xxxxx --name dev -# Then set RC_OUTPUT in your shell profile for that context -``` - -### Per-command - -```bash -rc apps list --output csv -``` - -The `--output` flag always takes precedence over the environment variable. diff --git a/docs/reference/pagination.md b/docs/reference/pagination.md deleted file mode 100644 index f0e7941..0000000 --- a/docs/reference/pagination.md +++ /dev/null @@ -1,118 +0,0 @@ -# Pagination - -RevenueCat CLI uses cursor-based pagination for all list commands. This approach is efficient for large datasets and avoids the inconsistencies of offset-based pagination. - -## How It Works - -Every list command returns a page of results along with a cursor pointing to the next page. You use that cursor with `--starting-after` to fetch the next page. - -``` -Page 1 Page 2 Page 3 -[item_1, item_2, ...] → [item_21, item_22, ...] → [item_41, ...] - ↑ ↑ - --starting-after=item_20 --starting-after=item_40 -``` - ---- - -## Pagination Flags - -| Flag | Description | Default | -|---|---|---| -| `--limit` | Number of items per page (1-100) | `20` | -| `--starting-after` | ID of the last item from the previous page | -- | -| `--all` | Automatically fetch all pages and combine results | `false` | - ---- - -## Manual Pagination - -Fetch results page by page using `--starting-after`: - -```bash -# First page -rc products list --limit 10 -``` - -The response includes a `next_page` field with the cursor value: - -```json -{ - "items": [...], - "next_page": "prod_xxxxx" -} -``` - -Use that value to fetch the next page: - -```bash -# Second page -rc products list --limit 10 --starting-after prod_xxxxx -``` - -When `next_page` is `null`, you have reached the end of the dataset. - ---- - -## Automatic Pagination - -Use `--all` to fetch every page automatically. The CLI handles cursor management internally and returns the combined result set. - -```bash -rc products list --all -``` - -!!! warning - Use `--all` with caution on large datasets. For projects with thousands of customers, prefer manual pagination or pipe to a file: - - ```bash - rc customers list --all --output csv > all-customers.csv - ``` - ---- - -## Combining with Output Formats - -Pagination works with every output format: - -```bash -# First 50 customers as a table -rc customers list --limit 50 --output table - -# All products as CSV -rc products list --all --output csv - -# Page through audit logs as YAML -rc audit-logs list --limit 25 --output yaml -``` - ---- - -## Scripting Example - -Loop through all pages in a shell script: - -```bash -#!/bin/bash -cursor="" - -while true; do - if [ -z "$cursor" ]; then - response=$(rc products list --limit 100 --output json) - else - response=$(rc products list --limit 100 --starting-after "$cursor" --output json) - fi - - # Process this page - echo "$response" | jq '.items[]' - - # Get next cursor - cursor=$(echo "$response" | jq -r '.next_page // empty') - - # Exit if no more pages - [ -z "$cursor" ] && break -done -``` - -!!! tip - For most use cases, `--all` is simpler than manual pagination. Reserve manual pagination for very large datasets where you want to process results incrementally. diff --git a/docs/reference/shell-completion.md b/docs/reference/shell-completion.md deleted file mode 100644 index 7ae0ce6..0000000 --- a/docs/reference/shell-completion.md +++ /dev/null @@ -1,96 +0,0 @@ -# Shell Completion - -RevenueCat CLI provides tab completion for commands, subcommands, and flags. Set it up once and never type a full command name again. - -## Setup - -=== "Bash" - - Add to `~/.bashrc`: - - ```bash - eval "$(rc completion bash)" - ``` - - Then reload your shell: - - ```bash - source ~/.bashrc - ``` - -=== "Zsh" - - Add to `~/.zshrc`: - - ```bash - eval "$(rc completion zsh)" - ``` - - Then reload your shell: - - ```bash - source ~/.zshrc - ``` - - !!! note - If you get `command not found: compdef`, add this **before** the eval line: - - ```bash - autoload -Uz compinit && compinit - ``` - -=== "Fish" - - ```bash - rc completion fish | source - ``` - - To make it permanent: - - ```bash - rc completion fish > ~/.config/fish/completions/rc.fish - ``` - -=== "PowerShell" - - Add to your PowerShell profile: - - ```powershell - rc completion powershell | Out-String | Invoke-Expression - ``` - - To find your profile path: - - ```powershell - echo $PROFILE - ``` - ---- - -## What Gets Completed - -Shell completion covers: - -- **Commands**: `rc app` + Tab completes to `rc apps` -- **Subcommands**: `rc apps` + Tab shows `list`, `get`, `create`, `update`, `delete`, `api-keys` -- **Flags**: `rc apps create --` + Tab shows `--name`, `--type`, `--bundle-id`, etc. - ---- - -## Verification - -After setup, test that completion is working: - -```bash -rc -``` - -You should see a list of all available command groups: - -``` -apps auth audit-logs customers -entitlements init metrics offerings -packages paywalls products projects -purchases subscriptions webhooks doctor -version completion -``` diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css deleted file mode 100644 index 2c19242..0000000 --- a/docs/stylesheets/extra.css +++ /dev/null @@ -1,12 +0,0 @@ -.md-header__topic .md-ellipsis { - font-weight: 700; -} - -.md-header__button.md-logo img { - height: 1.5rem; - width: auto; -} - -.md-header__button.md-logo + .md-header__topic { - display: flex; -} diff --git a/go.mod b/go.mod index 74f48cc..ed6c7ab 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.25.6 require ( github.com/spf13/cobra v1.10.2 github.com/spf13/viper v1.21.0 + golang.org/x/text v0.28.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -21,5 +22,4 @@ require ( github.com/subosito/gotenv v1.6.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.28.0 // indirect ) diff --git a/internal/api/client.go b/internal/api/client.go index 23f8c9a..daaa2ae 100644 --- a/internal/api/client.go +++ b/internal/api/client.go @@ -95,7 +95,7 @@ func (c *Client) Context() (context.Context, context.CancelFunc) { } // Do executes an API request -func (c *Client) Do(ctx context.Context, method, path string, body interface{}, result interface{}) error { +func (c *Client) Do(ctx context.Context, method, path string, body, result interface{}) error { url := c.baseURL + path var bodyReader io.Reader @@ -120,7 +120,7 @@ func (c *Client) Do(ctx context.Context, method, path string, body interface{}, if err != nil { return fmt.Errorf("request failed: %w", err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() respBody, err := io.ReadAll(resp.Body) if err != nil { diff --git a/internal/config/config.go b/internal/config/config.go index be19c59..2576507 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -83,7 +83,7 @@ func Init(cfgFile, profileName string) error { // Save saves the current configuration func Save() error { dir := filepath.Dir(configPath) - if err := os.MkdirAll(dir, 0700); err != nil { + if err := os.MkdirAll(dir, 0o700); err != nil { return fmt.Errorf("failed to create config directory: %w", err) } @@ -92,7 +92,7 @@ func Save() error { return fmt.Errorf("failed to marshal config: %w", err) } - if err := os.WriteFile(configPath, data, 0600); err != nil { + if err := os.WriteFile(configPath, data, 0o600); err != nil { return fmt.Errorf("failed to write config: %w", err) } diff --git a/internal/output/output.go b/internal/output/output.go index bdacf2b..c229eaf 100644 --- a/internal/output/output.go +++ b/internal/output/output.go @@ -78,7 +78,7 @@ func Print(data interface{}) error { func PrintSuccess(format string, args ...interface{}) { if !quietMode { msg := fmt.Sprintf(format, args...) - fmt.Fprintf(writer, "%s%s\u2713 %s%s\n", colorBold, colorGreen, msg, colorReset) + _, _ = fmt.Fprintf(writer, "%s%s\u2713 %s%s\n", colorBold, colorGreen, msg, colorReset) } } @@ -86,7 +86,7 @@ func PrintSuccess(format string, args ...interface{}) { func PrintInfo(format string, args ...interface{}) { if !quietMode { msg := fmt.Sprintf(format, args...) - fmt.Fprintf(writer, "%s%s%s\n", colorCyan, msg, colorReset) + _, _ = fmt.Fprintf(writer, "%s%s%s\n", colorCyan, msg, colorReset) } } @@ -116,51 +116,51 @@ func printJSON(data interface{}) error { return fmt.Errorf("failed to marshal JSON: %w", err) } - fmt.Fprintln(writer, string(output)) + _, _ = fmt.Fprintln(writer, string(output)) return nil } func printTable(data interface{}) error { w := tabwriter.NewWriter(writer, 0, 0, 2, ' ', 0) - defer w.Flush() + defer func() { _ = w.Flush() }() v := reflect.ValueOf(data) // Handle slice if v.Kind() == reflect.Slice { if v.Len() == 0 { - fmt.Fprintln(writer, "(no results)") + _, _ = fmt.Fprintln(writer, "(no results)") return nil } // Get headers from first element first := v.Index(0) - if first.Kind() == reflect.Ptr { + if first.Kind() == reflect.Pointer { first = first.Elem() } headers := getStructHeaders(first) - fmt.Fprintf(w, "%s%s%s\n", colorBold, strings.Join(headers, "\t"), colorReset) - fmt.Fprintln(w, strings.Repeat("-\t", len(headers))) + _, _ = fmt.Fprintf(w, "%s%s%s\n", colorBold, strings.Join(headers, "\t"), colorReset) + _, _ = fmt.Fprintln(w, strings.Repeat("-\t", len(headers))) // Print rows for i := 0; i < v.Len(); i++ { elem := v.Index(i) - if elem.Kind() == reflect.Ptr { + if elem.Kind() == reflect.Pointer { elem = elem.Elem() } values := getStructValues(elem) - fmt.Fprintln(w, strings.Join(values, "\t")) + _, _ = fmt.Fprintln(w, strings.Join(values, "\t")) } - } else if v.Kind() == reflect.Struct || (v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct) { + } else if v.Kind() == reflect.Struct || (v.Kind() == reflect.Pointer && v.Elem().Kind() == reflect.Struct) { // Single struct - if v.Kind() == reflect.Ptr { + if v.Kind() == reflect.Pointer { v = v.Elem() } headers := getStructHeaders(v) values := getStructValues(v) for i, h := range headers { - fmt.Fprintf(w, "%s:\t%s\n", h, values[i]) + _, _ = fmt.Fprintf(w, "%s:\t%s\n", h, values[i]) } } else { // Fallback to JSON @@ -176,18 +176,18 @@ func printMinimal(data interface{}) error { if v.Kind() == reflect.Slice { for i := 0; i < v.Len(); i++ { elem := v.Index(i) - if elem.Kind() == reflect.Ptr { + if elem.Kind() == reflect.Pointer { elem = elem.Elem() } // Print first field value if elem.Kind() == reflect.Struct && elem.NumField() > 0 { - fmt.Fprintln(writer, elem.Field(0).Interface()) + _, _ = fmt.Fprintln(writer, elem.Field(0).Interface()) } } } else if v.Kind() == reflect.Struct && v.NumField() > 0 { - fmt.Fprintln(writer, v.Field(0).Interface()) + _, _ = fmt.Fprintln(writer, v.Field(0).Interface()) } else { - fmt.Fprintln(writer, data) + _, _ = fmt.Fprintln(writer, data) } return nil @@ -203,20 +203,20 @@ func printTSV(data interface{}) error { // Print header first := v.Index(0) - if first.Kind() == reflect.Ptr { + if first.Kind() == reflect.Pointer { first = first.Elem() } headers := getStructHeaders(first) - fmt.Fprintln(writer, strings.Join(headers, "\t")) + _, _ = fmt.Fprintln(writer, strings.Join(headers, "\t")) // Print rows for i := 0; i < v.Len(); i++ { elem := v.Index(i) - if elem.Kind() == reflect.Ptr { + if elem.Kind() == reflect.Pointer { elem = elem.Elem() } values := getStructValues(elem) - fmt.Fprintln(writer, strings.Join(values, "\t")) + _, _ = fmt.Fprintln(writer, strings.Join(values, "\t")) } } else { return printJSON(data) @@ -238,7 +238,7 @@ func printCSV(data interface{}) error { // Print header first := v.Index(0) - if first.Kind() == reflect.Ptr { + if first.Kind() == reflect.Pointer { first = first.Elem() } headers := getStructHeaders(first) @@ -249,7 +249,7 @@ func printCSV(data interface{}) error { // Print rows for i := 0; i < v.Len(); i++ { elem := v.Index(i) - if elem.Kind() == reflect.Ptr { + if elem.Kind() == reflect.Pointer { elem = elem.Elem() } values := getStructValues(elem) @@ -269,7 +269,7 @@ func printYAML(data interface{}) error { if err != nil { return fmt.Errorf("failed to marshal YAML: %w", err) } - fmt.Fprint(writer, string(out)) + _, _ = fmt.Fprint(writer, string(out)) return nil } diff --git a/mkdocs.yml b/mkdocs.yml deleted file mode 100644 index 6790ccd..0000000 --- a/mkdocs.yml +++ /dev/null @@ -1,90 +0,0 @@ -site_name: RevenueCat CLI -site_url: https://androidpoet.github.io/revenuecat-cli -site_description: AI-powered subscription management companion for the command line -site_author: AndroidPoet -repo_url: https://github.com/AndroidPoet/revenuecat-cli -repo_name: AndroidPoet/revenuecat-cli - -theme: - name: material - logo: assets/logo-small.png - favicon: assets/logo-small.png - palette: - - scheme: default - primary: deep purple - accent: amber - toggle: - icon: material/brightness-7 - name: Switch to dark mode - - scheme: slate - primary: deep purple - accent: amber - toggle: - icon: material/brightness-4 - name: Switch to light mode - features: - - navigation.instant - - navigation.tracking - - navigation.tabs - - navigation.sections - - navigation.expand - - navigation.top - - search.suggest - - search.highlight - - content.code.copy - - content.code.annotate - icon: - repo: fontawesome/brands/github - -markdown_extensions: - - admonition - - pymdownx.details - - pymdownx.superfences - - pymdownx.highlight: - anchor_linenums: true - - pymdownx.inlinehilite - - pymdownx.tabbed: - alternate_style: true - - pymdownx.emoji: - emoji_index: !!python/name:material.extensions.emoji.twemoji - emoji_generator: !!python/name:material.extensions.emoji.to_svg - - attr_list - - md_in_html - - tables - - toc: - permalink: true - -nav: - - Home: index.md - - Getting Started: - - Installation: getting-started/installation.md - - Configuration: getting-started/configuration.md - - Quick Start: getting-started/quickstart.md - - Commands: - - Projects: commands/projects.md - - Apps: commands/apps.md - - Products: commands/products.md - - Entitlements: commands/entitlements.md - - Offerings: commands/offerings.md - - Packages: commands/packages.md - - Customers: commands/customers.md - - Subscriptions: commands/subscriptions.md - - Purchases: commands/purchases.md - - Paywalls: commands/paywalls.md - - Metrics: commands/metrics.md - - Webhooks: commands/webhooks.md - - Audit Logs: commands/audit-logs.md - - Auth: commands/auth.md - - Reference: - - Output Formats: reference/output-formats.md - - Pagination: reference/pagination.md - - Environment Variables: reference/environment-variables.md - - Shell Completion: reference/shell-completion.md - -extra_css: - - stylesheets/extra.css - -extra: - social: - - icon: fontawesome/brands/github - link: https://github.com/AndroidPoet/revenuecat-cli diff --git a/website/.gitignore b/website/.gitignore new file mode 100644 index 0000000..ab342a7 --- /dev/null +++ b/website/.gitignore @@ -0,0 +1,6 @@ +node_modules +.next +out +.DS_Store +*.log +.vercel diff --git a/website/components/Hero.jsx b/website/components/Hero.jsx new file mode 100644 index 0000000..e0fc37a --- /dev/null +++ b/website/components/Hero.jsx @@ -0,0 +1,38 @@ +import Link from 'next/link' + +const REPO = 'https://github.com/AndroidPoet/revenuecat-cli' + +const GitHubMark = () => ( + +) + +export function Hero() { + return ( +
+ + ) +} diff --git a/website/next.config.mjs b/website/next.config.mjs new file mode 100644 index 0000000..50ab713 --- /dev/null +++ b/website/next.config.mjs @@ -0,0 +1,19 @@ +import nextra from 'nextra' + +const withNextra = nextra({ + theme: 'nextra-theme-docs', + themeConfig: './theme.config.jsx', + defaultShowCopyCode: true, +}) + +// Served from https://androidpoet.github.io/revenuecat-cli/ — a GitHub Pages project +// site lives under a sub-path, so set basePath/assetPrefix accordingly. +const basePath = '/revenuecat-cli' + +export default withNextra({ + output: 'export', + images: { unoptimized: true }, + reactStrictMode: true, + basePath, + assetPrefix: basePath, +}) diff --git a/website/package.json b/website/package.json new file mode 100644 index 0000000..644454d --- /dev/null +++ b/website/package.json @@ -0,0 +1,23 @@ +{ + "name": "revenuecat-cli-docs", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "next": "^15.5.18", + "nextra": "^3.3.1", + "nextra-theme-docs": "^3.3.1", + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "pnpm": { + "overrides": { + "postcss@<8.5.10": "^8.5.10" + } + } +} diff --git a/website/pages/404.mdx b/website/pages/404.mdx new file mode 100644 index 0000000..49d73f0 --- /dev/null +++ b/website/pages/404.mdx @@ -0,0 +1,9 @@ +--- +title: Page not found +description: This page could not be found. +--- + +# 404 — Page not found + +That page doesn't exist. Head back to the [introduction](/) or jump to +[installation](/installation). diff --git a/website/pages/_app.jsx b/website/pages/_app.jsx new file mode 100644 index 0000000..98ff64b --- /dev/null +++ b/website/pages/_app.jsx @@ -0,0 +1,6 @@ +import 'nextra-theme-docs/style.css' +import '../styles/globals.css' + +export default function App({ Component, pageProps }) { + return +} diff --git a/website/pages/_meta.jsx b/website/pages/_meta.jsx new file mode 100644 index 0000000..dc424fc --- /dev/null +++ b/website/pages/_meta.jsx @@ -0,0 +1,15 @@ +export default { + index: 'Introduction', + installation: 'Installation', + 'getting-started': 'Getting Started', + usage: 'Usage', + commands: 'Command Reference', + configuration: 'Configuration', + 'output-formats': 'Output & Scripting', + github_link: { + title: 'GitHub', + type: 'page', + href: 'https://github.com/AndroidPoet/revenuecat-cli', + newWindow: true, + }, +} diff --git a/website/pages/commands/_meta.jsx b/website/pages/commands/_meta.jsx new file mode 100644 index 0000000..6498fb9 --- /dev/null +++ b/website/pages/commands/_meta.jsx @@ -0,0 +1,8 @@ +export default { + index: 'Overview', + setup: 'Setup & Auth', + catalog: 'Catalog', + customers: 'Customers & Subscriptions', + analytics: 'Analytics & Reports', + operations: 'Operations', +} diff --git a/website/pages/commands/analytics.mdx b/website/pages/commands/analytics.mdx new file mode 100644 index 0000000..81f715c --- /dev/null +++ b/website/pages/commands/analytics.mdx @@ -0,0 +1,47 @@ +--- +title: Analytics & Reports +description: metrics, charts, and full-project reports. +--- + +import { Callout } from 'nextra/components' + +# Analytics & Reports + +## `metrics` + +A quick numeric overview: MRR, active subscribers, trials, and revenue. + +```bash +rc metrics overview +rc metrics overview --output table +``` + +## `charts` + +21 chart types — revenue, MRR, ARR, churn, trials, LTV, retention, and more — with +time-series data and visual export. + +```bash +rc charts list # all available chart types +rc charts options revenue # filters, segments, resolutions for one chart +rc charts get revenue --resolution month --currency USD +rc charts export --format pdf --output charts.pdf +``` + +Export formats: `html`, `pdf`, `json`, `yaml`, `csv`. PDF export renders via headless +Chrome when available. + +## `report` + +Export an entire project's data as a single document. + +```bash +rc report --format html --output report.html +rc report --format pdf --output report.pdf +rc report --format json | jq '.products | length' +``` + + + Charts and reports honor the active `--project` / `--profile`, so you can script the same + export across environments. + diff --git a/website/pages/commands/catalog.mdx b/website/pages/commands/catalog.mdx new file mode 100644 index 0000000..12b8514 --- /dev/null +++ b/website/pages/commands/catalog.mdx @@ -0,0 +1,59 @@ +--- +title: Catalog +description: projects, apps, products, entitlements, offerings, and packages. +--- + +# Catalog + +These groups model your monetization catalog. Most support `list`, `get`, `create`, +`update`, and `delete`; entitlements and packages add `attach` / `detach`. + +## `projects` + +```bash +rc projects list +rc projects create --name "My App" +``` + +## `apps` + +```bash +rc apps list +rc apps get app_abc123 +rc apps create --name "iOS App" --type app_store +rc apps api-keys app_abc123 # list an app's public SDK keys +``` + +## `products` + +```bash +rc products list +rc products get prod_abc123 +rc products create --store app_store --store-identifier com.app.premium.monthly +rc products delete prod_abc123 +``` + +## `entitlements` + +```bash +rc entitlements list +rc entitlements create --lookup-key premium --display-name "Premium" +rc entitlements attach ent_abc123 --product-id prod_abc123 +rc entitlements detach ent_abc123 --product-id prod_abc123 +``` + +## `offerings` + +```bash +rc offerings list +rc offerings create --lookup-key default --display-name "Default" +rc offerings update off_abc123 --display-name "Renamed" +``` + +## `packages` + +```bash +rc packages list --offering-id off_abc123 +rc packages create --offering-id off_abc123 --lookup-key monthly +rc packages attach pkg_abc123 --product-id prod_abc123 +``` diff --git a/website/pages/commands/customers.mdx b/website/pages/commands/customers.mdx new file mode 100644 index 0000000..ae01c42 --- /dev/null +++ b/website/pages/commands/customers.mdx @@ -0,0 +1,38 @@ +--- +title: Customers & Subscriptions +description: customers, subscriptions, and purchases. +--- + +# Customers & Subscriptions + +## `customers` + +Full customer lifecycle, including attributes, aliases, and entitlements. + +```bash +rc customers list +rc customers get $APP_USER_ID +rc customers create --app-user-id user_123 +rc customers delete $APP_USER_ID +``` + +## `subscriptions` + +Inspect and manage active subscriptions. + +```bash +rc subscriptions get sub_abc123 +rc subscriptions list-entitlements sub_abc123 +rc subscriptions cancel sub_abc123 +rc subscriptions refund sub_abc123 +``` + +## `purchases` + +View one-time purchases and issue refunds. + +```bash +rc purchases get purch_abc123 +rc purchases list-entitlements purch_abc123 +rc purchases refund purch_abc123 +``` diff --git a/website/pages/commands/index.mdx b/website/pages/commands/index.mdx new file mode 100644 index 0000000..187f847 --- /dev/null +++ b/website/pages/commands/index.mdx @@ -0,0 +1,44 @@ +--- +title: Command Reference +description: Every RevenueCat CLI resource group and the actions it supports. +--- + +import { Cards } from 'nextra/components' + +# Command Reference + +RevenueCat CLI exposes **80+ commands** across **16 resource groups**, covering the full +RevenueCat API v2. Every command supports the [global flags](/usage#global-flags) and the +[output formats](/output-formats). + + + + + + + + + +## Groups at a glance + +| Group | Commands | What you can do | +|:------|:---------|:----------------| +| `auth` | `login` `switch` `list` `current` `delete` | Manage API key profiles | +| `init` | — | Bind the working directory to a project | +| `doctor` | — | Verify auth, access, and connectivity | +| `magicsetup` | — | One-click setup wizard for iOS / Android | +| `projects` | `list` `create` | Manage RevenueCat projects | +| `apps` | `list` `get` `create` `update` `delete` `api-keys` | Configure app store connections | +| `products` | `list` `get` `create` `delete` | Define subscription and one-time products | +| `entitlements` | `list` `get` `create` `update` `delete` `attach` `detach` | Control access to premium features | +| `offerings` | `list` `get` `create` `update` `delete` | Group packages for remote config | +| `packages` | `list` `get` `create` `update` `delete` `attach` `detach` | Bundle products inside offerings | +| `customers` | `list` `get` `create` `delete` + more | Customer lifecycle management | +| `subscriptions` | `get` `list-entitlements` `cancel` `refund` | Manage active subscriptions | +| `purchases` | `get` `list-entitlements` `refund` | View and refund purchases | +| `paywalls` | `list` `get` `create` `delete` | Manage paywall configurations | +| `metrics` | `overview` | MRR, active subscribers, trials, revenue | +| `charts` | `list` `get` `options` `export` | 21 chart types with visual export | +| `webhooks` | `list` `create` | Set up webhook integrations | +| `auditlogs` | `list` | Track changes and access history | +| `status` / `watch` / `diff` / `export` / `report` | — | Operations & monitoring | diff --git a/website/pages/commands/operations.mdx b/website/pages/commands/operations.mdx new file mode 100644 index 0000000..389ba42 --- /dev/null +++ b/website/pages/commands/operations.mdx @@ -0,0 +1,60 @@ +--- +title: Operations +description: status, watch, diff, export/import, paywalls, webhooks, and audit logs. +--- + +# Operations + +## `status` + +A one-command overview of the entire project — counts and health across resource groups. + +```bash +rc status +``` + +## `watch` + +An auto-refreshing terminal dashboard. + +```bash +rc watch metrics +``` + +## `diff` + +Compare entitlements and offerings between two projects. + +```bash +rc diff --source proj_a --target proj_b +``` + +## `export` / `import` + +Back up and migrate project configuration as YAML. + +```bash +rc export --project proj_a > proj_a.yaml +rc import --project proj_b --file proj_a.yaml --dry-run +``` + +## `paywalls` + +```bash +rc paywalls list +rc paywalls get pw_abc123 +rc paywalls create --offering-id off_abc123 +``` + +## `webhooks` + +```bash +rc webhooks list +rc webhooks create --url https://example.com/hooks/revenuecat +``` + +## `auditlogs` + +```bash +rc auditlogs list +``` diff --git a/website/pages/commands/setup.mdx b/website/pages/commands/setup.mdx new file mode 100644 index 0000000..12dc8df --- /dev/null +++ b/website/pages/commands/setup.mdx @@ -0,0 +1,46 @@ +--- +title: Setup & Auth +description: auth, init, doctor, and the magicsetup wizard. +--- + +# Setup & Auth + +## `auth` — API key profiles + +Store and switch between multiple secret API keys. + +```bash +rc auth login --api-key sk_your_key_here # save under the default profile +rc auth login --api-key sk_other --profile prod # save a named profile +rc auth list # list saved profiles +rc auth current # show the active profile +rc auth switch prod # change the active profile +rc auth delete prod # remove a profile +``` + +## `init` — bind a project + +Writes a local `.rc.yaml` so commands in this directory default to the given project. + +```bash +rc init --project proj_your_project_id +``` + +## `doctor` — health check + +Validates auth, project access, and connectivity, reporting each check as `OK` or `FAIL`. + +```bash +rc doctor +``` + +## `magicsetup` — one-click wizard + +Sets up an entire offering stack — apps, products, entitlements, offerings, and packages, +all wired together — for iOS, Android, or both, from preset templates (Freemium, Paywall, +Trial, Tiered, Consumable). + +```bash +rc magicsetup # interactive wizard +rc magicsetup --dry-run # preview everything first +``` diff --git a/website/pages/configuration.mdx b/website/pages/configuration.mdx new file mode 100644 index 0000000..19022d7 --- /dev/null +++ b/website/pages/configuration.mdx @@ -0,0 +1,60 @@ +--- +title: Configuration +description: Config files, project binding, and environment variables. +--- + +# Configuration + +RevenueCat CLI reads configuration from three places, in increasing precedence: + +1. The global config file (auth profiles). +2. A project-local `.rc.yaml` (written by `rc init`). +3. Environment variables and command-line flags. + +## Global config + +Auth profiles live in the user config directory (by default +`$HOME/.revenuecat-cli/config.json`). Override the path with `--config` or by setting up a +profile via `rc auth login`. You rarely edit this file by hand — use the `auth` commands. + +## Project config (`.rc.yaml`) + +`rc init --project proj_xyz` writes a `.rc.yaml` in the current directory: + +```yaml +project: proj_xyz +``` + +Any command run from this directory (or a subdirectory) picks up that project unless you +pass `--project` / `-p` explicitly. `.rc.yaml` is safe to commit if it contains only a +project ID — never put secret keys in it. + +## Environment variables + +Every core setting has an `RC_*` environment variable, which is ideal for CI: + +| Variable | Maps to | +|:---------|:--------| +| `RC_API_KEY` | Secret API key (bypasses stored profiles) | +| `RC_PROJECT` | `--project` | +| `RC_PROFILE` | `--profile` | +| `RC_OUTPUT` | `--output` | +| `RC_DEBUG` | `--debug` | +| `RC_TIMEOUT` | `--timeout` | + +Example CI usage: + +```bash +export RC_API_KEY=sk_ci_key +export RC_PROJECT=proj_xyz +export RC_OUTPUT=json +rc products list | jq '.items | length' +``` + +## Precedence + +For any setting, the most specific source wins: + +``` +flag > RC_* env var > .rc.yaml > global config +``` diff --git a/website/pages/getting-started.mdx b/website/pages/getting-started.mdx new file mode 100644 index 0000000..273e26a --- /dev/null +++ b/website/pages/getting-started.mdx @@ -0,0 +1,71 @@ +--- +title: Getting Started +description: Authenticate, point the CLI at a project, and run your first commands. +--- + +import { Steps, Callout } from 'nextra/components' + +# Getting Started + +This walks you from a fresh install to your first real commands. + + + +### Get an API key + +Create a **secret** API key (v2) in the RevenueCat dashboard at +[app.revenuecat.com/settings/api-keys](https://app.revenuecat.com/settings/api-keys). Secret +keys start with `sk_`. + + + Secret keys can mutate your project. Treat them like passwords — prefer the `RC_API_KEY` + environment variable or a named profile over pasting keys into shared scripts. + + +### Authenticate + +```bash +rc auth login --api-key sk_your_key_here +``` + +This stores the key in a named profile (default: `default`). Manage profiles with +`rc auth list`, `rc auth switch `, `rc auth current`, and `rc auth delete `. + +### Select a project + +```bash +rc init --project proj_your_project_id +``` + +`init` writes a local `.rc.yaml` so commands run in this directory default to that project. +You can always override per-command with `--project` / `-p`, or set `RC_PROJECT`. + +### Confirm everything works + +```bash +rc doctor +``` + +`doctor` checks your auth, project access, and connectivity, and reports each as `OK` or +`FAIL`. + +### Run your first commands + +```bash +# A one-screen overview of the whole project +rc status + +# List products as a table +rc products list --output table + +# Pipe JSON into jq +rc offerings list | jq '.items[] | {id, identifier}' +``` + + + +## Next steps + +- [Usage](/usage) — global flags, dry-run, profiles, and common workflows. +- [Command Reference](/commands) — every resource group and what it can do. +- [Output & Scripting](/output-formats) — formats, pagination, and CI patterns. diff --git a/website/pages/index.mdx b/website/pages/index.mdx new file mode 100644 index 0000000..106b80a --- /dev/null +++ b/website/pages/index.mdx @@ -0,0 +1,50 @@ +--- +title: RevenueCat CLI +description: A fast, scriptable command-line tool for RevenueCat — subscriptions, products, offerings, charts, and reports, with JSON-first output built for CI/CD. +--- + +import { Hero } from '../components/Hero' +import { Cards } from 'nextra/components' + + + +**RevenueCat CLI** brings the full RevenueCat API v2 to your terminal. Create and inspect +products, entitlements, offerings and packages, manage customers and subscriptions, pull +chart data, and export whole-project reports — all from scripts, CI pipelines, or an +interactive shell. Every command speaks JSON by default, so output pipes straight into +`jq` and automation. + +```bash +# Authenticate, point at a project, and check everything is wired up +rc auth login --api-key sk_your_key_here +rc init --project proj_your_project_id +rc doctor + +# List your products as a table, or as JSON for scripting +rc products list --output table +rc products list | jq '.items[].identifier' +``` + +## Why RevenueCat CLI + +- **JSON-first, automation-ready.** Default output is structured JSON; `--output table`, + `csv`, `tsv`, `yaml`, and `minimal` are available when a human is reading. +- **Full API v2 coverage.** 80+ commands across 16 resource groups — projects, apps, + products, entitlements, offerings, packages, customers, subscriptions, purchases, + paywalls, metrics, charts, webhooks, and audit logs. +- **Predictable for CI/CD.** No interactive prompts in normal commands, explicit flags + over cryptic shortcuts, and clean exit codes (`0` success, `1` error, `2` validation). +- **Dry-run anything.** `--dry-run` previews mutations before they touch your project. +- **Profiles & env.** Manage multiple API keys with named auth profiles, or drive + everything from `RC_*` environment variables. + +## Explore the docs + + + + + + + + + diff --git a/website/pages/installation.mdx b/website/pages/installation.mdx new file mode 100644 index 0000000..b79627f --- /dev/null +++ b/website/pages/installation.mdx @@ -0,0 +1,88 @@ +--- +title: Installation +description: Install RevenueCat CLI via Homebrew, go install, a prebuilt binary, or from source. +--- + +import { Tabs, Callout } from 'nextra/components' + +# Installation + +RevenueCat CLI ships as a single static binary. The command is `revenuecat-cli`, with +`rc` available as a short alias. + + + + + +```bash +brew tap AndroidPoet/tap +brew install revenuecat-cli +``` + +Upgrade later with `brew upgrade revenuecat-cli`. + + + + + +Requires Go 1.21 or newer: + +```bash +go install github.com/AndroidPoet/revenuecat-cli/cmd/revenuecat-cli@latest +``` + +The binary lands in `$(go env GOPATH)/bin` — make sure that's on your `PATH`. + + + + + +Download the archive for your platform from the +[releases page](https://github.com/AndroidPoet/revenuecat-cli/releases/latest), extract it, +and move the binary onto your `PATH`: + +```bash +tar -xzf revenuecat-cli_*_darwin_arm64.tar.gz +sudo mv revenuecat-cli /usr/local/bin/ +``` + + + + + +```bash +git clone https://github.com/AndroidPoet/revenuecat-cli.git +cd revenuecat-cli +make build # produces ./bin/revenuecat-cli +make install # copies it to $GOPATH/bin +``` + + + + + +## Verify + +```bash +revenuecat-cli version +# revenuecat-cli v0.5.0 +# commit: a1b2c3d +# built: 2026-06-19T00:00:00Z +``` + +## Shell completion + +RevenueCat CLI generates completion scripts for bash, zsh, fish, and PowerShell, and many +flags (`--app-id`, `--product-id`, …) offer live, API-powered completions. + +```bash +# zsh +rc completion zsh > "${fpath[1]}/_revenuecat-cli" + +# bash +rc completion bash | sudo tee /etc/bash_completion.d/revenuecat-cli +``` + + + Run `rc completion --help` to see the exact install instructions for your shell. + diff --git a/website/pages/output-formats.mdx b/website/pages/output-formats.mdx new file mode 100644 index 0000000..c847b03 --- /dev/null +++ b/website/pages/output-formats.mdx @@ -0,0 +1,77 @@ +--- +title: Output & Scripting +description: Output formats, pagination, exit codes, and CI patterns. +--- + +import { Callout } from 'nextra/components' + +# Output & Scripting + +RevenueCat CLI is built to be driven by scripts. Output defaults to JSON; pick a +human-friendly format with `--output` / `-o` when you need one. + +## Formats + +| Format | Flag | Best for | +|:-------|:-----|:---------| +| JSON | `-o json` (default) | Piping into `jq`, automation | +| Table | `-o table` | Reading in a terminal | +| Minimal | `-o minimal` | IDs only, one per line | +| TSV | `-o tsv` | `cut` / `awk` pipelines | +| CSV | `-o csv` | Spreadsheets | +| YAML | `-o yaml` | Human-readable structured data | + +```bash +rc products list -o table +rc products list -o minimal # just identifiers +rc products list | jq '.items[].id' # JSON + jq +rc products list -o csv > products.csv +``` + +Add `--pretty` to indent JSON, or `--quiet` / `-q` to drop progress noise. + +## Pagination + +List commands paginate. Use the standard flags to page through large result sets: + +```bash +rc customers list --limit 100 +rc customers list --limit 100 --starting-after cust_lastid +``` + +JSON list responses carry an `items` array plus paging metadata you can follow in a loop. + +## Exit codes + +``` +0 success +1 runtime / API error +2 validation error (bad flags or input) +``` + +Branch on them in scripts: + +```bash +if rc doctor -q; then + echo "healthy" +else + echo "check failed (exit $?)" >&2 + exit 1 +fi +``` + +## CI patterns + +```bash +# Fail a pipeline if a project has no active offerings +count=$(rc offerings list -o json | jq '.items | length') +[ "$count" -gt 0 ] || { echo "no offerings"; exit 1; } + +# Preview mutations in a PR check +rc import --file desired.yaml --dry-run +``` + + + Use `--debug` while developing a script to see the exact API requests and responses, then + drop it for production runs. + diff --git a/website/pages/usage.mdx b/website/pages/usage.mdx new file mode 100644 index 0000000..c00474f --- /dev/null +++ b/website/pages/usage.mdx @@ -0,0 +1,92 @@ +--- +title: Usage +description: Global flags, dry-run, profiles, and the everyday command structure of RevenueCat CLI. +--- + +import { Callout } from 'nextra/components' + +# Usage + +## Command structure + +Commands follow a consistent `rc [flags]` shape: + +```bash +rc [args] [flags] +``` + +For example: + +```bash +rc products list +rc products get prod_abc123 +rc entitlements create --lookup-key premium --display-name "Premium" +rc subscriptions cancel sub_abc123 +``` + +Run `rc --help` for the full command tree, or `rc --help` for a single group. + +## Global flags + +These persistent flags work on every command: + +| Flag | Default | Description | +|:-----|:--------|:------------| +| `--project`, `-p` | — | RevenueCat project ID (or `RC_PROJECT`) | +| `--profile` | `default` | Auth profile name (or `RC_PROFILE`) | +| `--output`, `-o` | `json` | Output format: `json`, `table`, `minimal`, `tsv`, `csv`, `yaml` | +| `--pretty` | `false` | Pretty-print JSON output | +| `--quiet`, `-q` | `false` | Suppress non-essential output | +| `--debug` | `false` | Print API requests/responses | +| `--timeout` | `60s` | Request timeout | +| `--dry-run` | `false` | Preview changes without applying them | +| `--config` | — | Path to a config file | + +## Dry-run mutations + +Any command that changes state respects `--dry-run`, printing exactly what *would* happen +without calling the API: + +```bash +rc offerings create --lookup-key default --display-name "Default" --dry-run +``` + + + Use `--dry-run` in pull-request CI to surface intended changes in review before they ship. + + +## Profiles and environments + +Named profiles let you keep separate credentials for, say, staging and production: + +```bash +rc auth login --api-key sk_staging_key --profile staging +rc auth login --api-key sk_prod_key --profile prod + +rc products list --profile staging +RC_PROFILE=prod rc products list +``` + +## Exit codes + +Exit codes are stable so scripts can branch on them: + +| Code | Meaning | +|:-----|:--------| +| `0` | Success | +| `1` | Runtime / API error | +| `2` | Validation error (bad flags or input) | + +## Common workflows + +```bash +# Snapshot a project's config to YAML, then diff two projects +rc export --project proj_a > proj_a.yaml +rc diff --source proj_a --target proj_b + +# Live metrics dashboard that refreshes in the terminal +rc watch metrics + +# Full project report as a PDF +rc report --format pdf --output report.pdf +``` diff --git a/website/pnpm-lock.yaml b/website/pnpm-lock.yaml new file mode 100644 index 0000000..b5107cd --- /dev/null +++ b/website/pnpm-lock.yaml @@ -0,0 +1,4142 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + postcss@<8.5.10: ^8.5.10 + +importers: + + .: + dependencies: + next: + specifier: ^15.5.18 + version: 15.5.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + nextra: + specifier: ^3.3.1 + version: 3.3.1(@types/react@19.2.17)(next@15.5.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@6.0.3) + nextra-theme-docs: + specifier: ^3.3.1 + version: 3.3.1(next@15.5.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@3.3.1(@types/react@19.2.17)(next@15.5.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@6.0.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + +packages: + + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + + '@braintree/sanitize-url@7.1.2': + resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} + + '@chevrotain/types@11.1.2': + resolution: {integrity: sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==} + + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} + + '@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/react-dom@2.1.8': + resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/react@0.26.28': + resolution: {integrity: sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + + '@formatjs/intl-localematcher@0.5.10': + resolution: {integrity: sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==} + + '@headlessui/react@2.2.10': + resolution: {integrity: sha512-5pVLNK9wlpxTUTy9GpgbX/SdcRh+HBnPktjM2wbiLTH4p+2EPHBO1aoSryUCuKUIItdDWO9ITlhUL8UnUN/oIA==} + engines: {node: '>=10'} + peerDependencies: + react: ^18 || ^19 || ^19.0.0-rc + react-dom: ^18 || ^19 || ^19.0.0-rc + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@3.1.3': + resolution: {integrity: sha512-LPKOXPn/zV+zis1oOfGWogaXVpqUybF3ZS6SCZIsz8vg0ivVp9+fVqyYB7xq0aiST/VhUQYGO1qo6uoYSiEJqw==} + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@internationalized/date@3.12.2': + resolution: {integrity: sha512-FY1Y+H64NDs+HAF6omlnWxm3mEpfgaCSWtL5l551ZZfImA+kGjPFgrnJrGjH6lfmLL0g8Z/mBu1R3kufeCp6Jw==} + + '@internationalized/number@3.6.7': + resolution: {integrity: sha512-3ji1fcrT+FPAK86UqEhB/psHixYo6niWPJtt7+qRaYFynt/BaJG8GhAPimtWUpEiVSTq8ZM8L5psMxGquiB/Vg==} + + '@internationalized/string@3.2.9': + resolution: {integrity: sha512-kzP/M/mbQxODlmOt4bIQZ2SBVUWUSqMLXooXixnX7noche8WHaQcA+nwFN1K2KCF/cp+LDUhcJsCicwkvhD1pg==} + + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + + '@mermaid-js/parser@1.1.1': + resolution: {integrity: sha512-VuHdsYMK1bT6X2JbcAaWAhugTRvRBRyuZgd+c22swUeI9g/ntaxF7CY7dYarhZovofCbUNO0G7JesfmNtjYOCw==} + + '@napi-rs/simple-git-android-arm-eabi@0.1.22': + resolution: {integrity: sha512-JQZdnDNm8o43A5GOzwN/0Tz3CDBQtBUNqzVwEopm32uayjdjxev1Csp1JeaqF3v9djLDIvsSE39ecsN2LhCKKQ==} + engines: {node: '>= 10'} + cpu: [arm] + os: [android] + + '@napi-rs/simple-git-android-arm64@0.1.22': + resolution: {integrity: sha512-46OZ0SkhnvM+fapWjzg/eqbJvClxynUpWYyYBn4jAj7GQs1/Yyc8431spzDmkA8mL0M7Xo8SmbkzTDE7WwYAfg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@napi-rs/simple-git-darwin-arm64@0.1.22': + resolution: {integrity: sha512-zH3h0C8Mkn9//MajPI6kHnttywjsBmZ37fhLX/Fiw5XKu84eHA6dRyVtMzoZxj6s+bjNTgaMgMUucxPn9ktxTQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@napi-rs/simple-git-darwin-x64@0.1.22': + resolution: {integrity: sha512-GZN7lRAkGKB6PJxWsoyeYJhh85oOOjVNyl+/uipNX8bR+mFDCqRsCE3rRCFGV9WrZUHXkcuRL2laIRn7lLi3ag==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@napi-rs/simple-git-freebsd-x64@0.1.22': + resolution: {integrity: sha512-xyqX1C5I0WBrUgZONxHjZH5a4LqQ9oki3SKFAVpercVYAcx3pq6BkZy1YUOP4qx78WxU1CCNfHBN7V+XO7D99A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@napi-rs/simple-git-linux-arm-gnueabihf@0.1.22': + resolution: {integrity: sha512-4LOtbp9ll93B9fxRvXiUJd1/RM3uafMJE7dGBZGKWBMGM76+BAcCEUv2BY85EfsU/IgopXI6n09TycRfPWOjxA==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@napi-rs/simple-git-linux-arm64-gnu@0.1.22': + resolution: {integrity: sha512-GVOjP/JjCzbQ0kSqao7ctC/1sodVtv5VF57rW9BFpo2y6tEYPCqHnkQkTpieuwMNe+TVOhBUC1+wH0d9/knIHg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@napi-rs/simple-git-linux-arm64-musl@0.1.22': + resolution: {integrity: sha512-MOs7fPyJiU/wqOpKzAOmOpxJ/TZfP4JwmvPad/cXTOWYwwyppMlXFRms3i98EU3HOazI/wMU2Ksfda3+TBluWA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@napi-rs/simple-git-linux-ppc64-gnu@0.1.22': + resolution: {integrity: sha512-L59dR30VBShRUIZ5/cQHU25upNgKS0AMQ7537J6LCIUEFwwXrKORZKJ8ceR+s3Sr/4jempWVvMdjEpFDE4HYww==} + engines: {node: '>= 10'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@napi-rs/simple-git-linux-s390x-gnu@0.1.22': + resolution: {integrity: sha512-4FHkPlCSIZUGC6HiADffbe6NVoTBMd65pIwcd40IDbtFKOgFMBA+pWRqKiQ21FERGH16Zed7XHJJoY3jpOqtmQ==} + engines: {node: '>= 10'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@napi-rs/simple-git-linux-x64-gnu@0.1.22': + resolution: {integrity: sha512-Ei1tM5Ho/dwknF3pOzqkNW9Iv8oFzRxE8uOhrITcdlpxRxVrBVptUF6/0WPdvd7R9747D/q61QG/AVyWsWLFKw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@napi-rs/simple-git-linux-x64-musl@0.1.22': + resolution: {integrity: sha512-zRYxg7it0p3rLyEJYoCoL2PQJNgArVLyNavHW03TFUAYkYi5bxQ/UFNVpgxMaXohr5yu7qCBqeo9j4DWeysalg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@napi-rs/simple-git-win32-arm64-msvc@0.1.22': + resolution: {integrity: sha512-XGFR1fj+Y9cWACcovV2Ey/R2xQOZKs8t+7KHPerYdJ4PtjVzGznI4c2EBHXtdOIYvkw7tL5rZ7FN1HJKdD5Quw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@napi-rs/simple-git-win32-ia32-msvc@0.1.22': + resolution: {integrity: sha512-Gqr9Y0gs6hcNBA1IXBpoqTFnnIoHuZGhrYqaZzEvGMLrTrpbXrXVEtX3DAAD2RLc1b87CPcJ49a7sre3PU3Rfw==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@napi-rs/simple-git-win32-x64-msvc@0.1.22': + resolution: {integrity: sha512-hQjcreHmUcpw4UrtkOron1/TQObfe484lxiXFLLUj7aWnnnOVs1mnXq5/Bo9+3NYZldFpFRJPdPBeHCisXkKJg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@napi-rs/simple-git@0.1.22': + resolution: {integrity: sha512-bMVoAKhpjTOPHkW/lprDPwv5aD4R4C3Irt8vn+SKA9wudLe9COLxOhurrKRsxmZccUbWXRF7vukNeGUAj5P8kA==} + engines: {node: '>= 10'} + + '@next/env@15.5.19': + resolution: {integrity: sha512-sWWluFvcv5v3Fxznmf2ZfjyoVQt/64oCnYqS90inQWGzMPK1VjvekPiz3OPHKmFT30EnHrjlbyaHLt3M0vWabw==} + + '@next/swc-darwin-arm64@15.5.19': + resolution: {integrity: sha512-jx9wWlTKueHKPvVOndyr7WuaevWCkuYqsQ8gC0TMPKAVWG3MhcdMrjfo9tvIZNXd0QOUYXXvAcZ325y8Uq7uzg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@15.5.19': + resolution: {integrity: sha512-291KFcsIQ3OenRdiUDFOR6W3wezzH4auENXm1gbm1Bjd4ANMMRgxPrWTUztQN43BnVoVuMnHCrLeECIMwgFKbA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@15.5.19': + resolution: {integrity: sha512-WeH+nelQyyMeE2f8FxBRZNrGipya5zHZV2vjzfCOAYyiI6am+NbnWAAldOBFQBB2w0DjJcsvrKqoFT2b7+5YoA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@next/swc-linux-arm64-musl@15.5.19': + resolution: {integrity: sha512-5xTOE0lDlDCSSfp+BAif7j17VRRCjWp//ZPZy6NI0QpdrhxtQnsZguSx0xAAZ0c9XZLrLLwCe/XVe5YPrRilKw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@next/swc-linux-x64-gnu@15.5.19': + resolution: {integrity: sha512-LTxRmMgqqMv05Had879W00Fm53quiJd3Zuz8h1JSNJ3nGSlbZ/7Tjs1tKyScgN3Au3t3MyPsjPlq60fMmSHLsg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@next/swc-linux-x64-musl@15.5.19': + resolution: {integrity: sha512-eoNQSpA5PQfB9wBO4RA47MTDXWz1fizy9Y3Z6e4DetYIF3dvjuu8sj7aIGn/bFCU6lnFzTK34NtCaffP4NsQ7Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@next/swc-win32-arm64-msvc@15.5.19': + resolution: {integrity: sha512-6UNt2dFuCHOe446sm/Kp69nUe8/wIhnh9bm6Xcqw4qEWCOppLMOvhTBVgvM7invVUNr4SPpP6NOQsACtn2IN9Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.5.19': + resolution: {integrity: sha512-PhmojAHyqMne56HBLGu9dhDnHPuFmEjrXSQMM/nW0J6j849lk3ESrVtqNJcCk8CKOV7brpTTbaYAjwKPzKM69w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@react-aria/focus@3.22.1': + resolution: {integrity: sha512-CPxtkyrBi/HYY5P3lE/57sQ6qfa0lN8E55TOm89H0kNGv0lKt+/0zP7lWERzBjRr5IxBVrQX4gFEowBN52LPaA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/interactions@3.28.1': + resolution: {integrity: sha512-Bqb+HrD5I5MHS2SKBhISYqo2SW8Y2dfzgF/Y1lIJq7xqLxheo9vzxPGEHhz+XzkgGfoqEJx8A6a3C7uiqS3HWA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/shared@3.36.0': + resolution: {integrity: sha512-DkP/H0C2YjjS7gZWKNqOmU8a16qHPjQNdzMwmTq9SzplM6Iw0kVMTZ0OIoe6FOgGqa+FwMsE2QbPjh/n3g/jXQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@shikijs/core@1.29.2': + resolution: {integrity: sha512-vju0lY9r27jJfOY4Z7+Rt/nIOjzJpZ3y+nYpqtUZInVoXQ/TJZcfGnNOGnKjFdVZb8qexiCuSlZRKcGfhhTTZQ==} + + '@shikijs/engine-javascript@1.29.2': + resolution: {integrity: sha512-iNEZv4IrLYPv64Q6k7EPpOCE/nuvGiKl7zxdq0WFuRPF5PAE9PRo2JGq/d8crLusM59BRemJ4eOqrFrC4wiQ+A==} + + '@shikijs/engine-oniguruma@1.29.2': + resolution: {integrity: sha512-7iiOx3SG8+g1MnlzZVDYiaeHe7Ez2Kf2HrJzdmGwkRisT7r4rak0e655AcM/tF9JG/kg5fMNYlLLKglbN7gBqA==} + + '@shikijs/langs@1.29.2': + resolution: {integrity: sha512-FIBA7N3LZ+223U7cJDUYd5shmciFQlYkFXlkKVaHsCPgfVLiO+e12FmQE6Tf9vuyEsFe3dIl8qGWKXgEHL9wmQ==} + + '@shikijs/themes@1.29.2': + resolution: {integrity: sha512-i9TNZlsq4uoyqSbluIcZkmPL9Bfi3djVxRnofUHwvx/h6SRW3cwgBC5SML7vsDcWyukY0eCzVN980rqP6qNl9g==} + + '@shikijs/twoslash@1.29.2': + resolution: {integrity: sha512-2S04ppAEa477tiaLfGEn1QJWbZUmbk8UoPbAEw4PifsrxkBXtAtOflIZJNtuCwz8ptc/TPxy7CO7gW4Uoi6o/g==} + + '@shikijs/types@1.29.2': + resolution: {integrity: sha512-VJjK0eIijTZf0QSTODEXCqinjBn0joAHQ+aPSBzrv4O2d/QSbsMw+ZeSRx03kV34Hy7NzUvV/7NqfYGRLrASmw==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@swc/helpers@0.5.23': + resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} + + '@tanstack/react-virtual@3.14.3': + resolution: {integrity: sha512-k/cnHPVaOfn46hSbiY6n4Dzf4QjCGWSF40zR5QIIYUqPAjpA6TN7InfYmcMiDVQGP2iUn9xsRbAl8u1v3UmeVQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tanstack/virtual-core@3.17.1': + resolution: {integrity: sha512-VZyW2Uiml5tmBZwPGrSD3Sz73OxzljQMCmzYHsUTPEuTsERf5xwa+uWb01xEzkz3ZSYTjj8NEb/mKHvgKxyZdA==} + + '@theguild/remark-mermaid@0.1.3': + resolution: {integrity: sha512-2FjVlaaKXK7Zj7UJAgOVTyaahn/3/EAfqYhyXg0BfDBVUl+lXcoIWRaxzqfnDr2rv8ax6GsC5mNh6hAaT86PDw==} + peerDependencies: + react: ^18.2.0 + + '@theguild/remark-npm2yarn@0.3.3': + resolution: {integrity: sha512-ma6DvR03gdbvwqfKx1omqhg9May/VYGdMHvTzB4VuxkyS7KzfZ/lzrj43hmcsggpMje0x7SADA/pcMph0ejRnA==} + + '@types/d3-array@3.2.2': + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} + + '@types/d3-axis@3.0.6': + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} + + '@types/d3-brush@3.0.6': + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} + + '@types/d3-chord@3.0.6': + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-contour@3.0.6': + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} + + '@types/d3-delaunay@6.0.4': + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} + + '@types/d3-dispatch@3.0.7': + resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==} + + '@types/d3-drag@3.0.7': + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} + + '@types/d3-dsv@3.0.7': + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-fetch@3.0.7': + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} + + '@types/d3-force@3.0.10': + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} + + '@types/d3-format@3.0.4': + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + + '@types/d3-geo@3.1.0': + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} + + '@types/d3-hierarchy@3.1.7': + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-polygon@3.0.2': + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} + + '@types/d3-quadtree@3.0.6': + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} + + '@types/d3-random@3.0.3': + resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} + + '@types/d3-scale-chromatic@3.1.0': + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-selection@3.0.11': + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} + + '@types/d3-shape@3.1.8': + resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==} + + '@types/d3-time-format@4.0.3': + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + + '@types/d3-transition@3.0.9': + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} + + '@types/d3-zoom@3.0.8': + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} + + '@types/d3@7.4.3': + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/geojson@7946.0.16': + resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/katex@0.16.8': + resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdx@2.0.14': + resolution: {integrity: sha512-T48PeuJtvLosNTPVhfnIp3i/n3a4g4Bad7YCq5k64D4u7NwDrAotikQ+5+sjtUvBmxCMlbo3dVL+C2dP0rWHzg==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/nlcst@2.0.3': + resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} + + '@types/react@19.2.17': + resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@typescript/vfs@1.6.4': + resolution: {integrity: sha512-PJFXFS4ZJKiJ9Qiuix6Dz/OwEIqHD7Dme1UwZhTK11vR+5dqW2ACbdndWQexBzCx+CPuMe5WBYQWCsFyGlQLlQ==} + peerDependencies: + typescript: '*' + + '@ungap/structured-clone@1.3.1': + resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==} + + '@upsetjs/venn.js@2.0.0': + resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==} + + '@xmldom/xmldom@0.9.10': + resolution: {integrity: sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==} + engines: {node: '>=14.6'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + engines: {node: '>=0.4.0'} + hasBin: true + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + array-iterate@2.0.1: + resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + better-react-mathjax@2.3.0: + resolution: {integrity: sha512-K0ceQC+jQmB+NLDogO5HCpqmYf18AU2FxDbLdduYgkHYWZApFggkHE4dIaXCV1NqeoscESYXXo1GSkY6fA295w==} + peerDependencies: + react: '>=16.8' + + caniuse-lite@1.0.30001799: + resolution: {integrity: sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==} + + 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==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + clipboardy@4.0.0: + resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==} + engines: {node: '>=18'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + compute-scroll-into-view@3.1.1: + resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==} + + cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + + cose-base@2.2.0: + resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + cytoscape-cose-bilkent@4.1.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape-fcose@2.2.0: + resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape@3.34.0: + resolution: {integrity: sha512-62rNSrioXw93uliKFBwjukeQyeWwH2PqDrTac31r2P6464u3AUvTk0xS4LVvT251g7IgkFunrI48ZEZGjywSOg==} + engines: {node: '>=0.10'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.2: + resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + + dagre-d3-es@7.0.14: + resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==} + + dayjs@1.11.21: + resolution: {integrity: sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==} + + 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==} + + delaunator@5.1.0: + resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} + + 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.4.11: + resolution: {integrity: sha512-zhlUV12GsaRzMsf9q5M254YhA4+VuF0fG+QFqu6aYpoGlKtz+w8//jBcGVYBgQkR5GHjUomejY84AV+/uPbWdw==} + + emoji-regex-xs@1.0.0: + resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + es-toolkit@1.47.1: + resolution: {integrity: sha512-5RAqEwf4P4E17p+W75KLOWw/nOvKZzSQpxM32IpI2KZLaVonjTrZ0Ai5ghMaVI9eKC2p8eoQgcBdkEDgzFk6+Q==} + + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + esm@3.2.25: + resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==} + engines: {node: '>=6'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-value-to-estree@3.5.0: + resolution: {integrity: sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fault@2.0.1: + resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} + + flexsearch@0.7.43: + resolution: {integrity: sha512-c5o/+Um8aqCSOXGcZoqZOm+NqtVwNsvVpWv6lfmSclU954O3wvQKxxK8zj74fPaSJbXpSLTs4PRhh+wnoCXnKg==} + + format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + + hachure-fill@0.5.2: + resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} + + hast-util-from-dom@5.0.1: + resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==} + + hast-util-from-html-isomorphic@2.0.0: + resolution: {integrity: sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==} + + 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-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-parse5@8.0.1: + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} + + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + + 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==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + + is64bit@2.0.0: + resolution: {integrity: sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw==} + engines: {node: '>=18'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + katex@0.16.47: + resolution: {integrity: sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==} + hasBin: true + + khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + + layout-base@2.0.1: + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + + lodash-es@4.18.1: + resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + marked@16.4.2: + resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==} + engines: {node: '>= 20'} + hasBin: true + + mathjax-full@3.2.2: + resolution: {integrity: sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==} + deprecated: Version 4 replaces this package with the scoped package @mathjax/src + + 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-frontmatter@2.0.1: + resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} + + 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-math@3.0.0: + resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + 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==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + mermaid@11.15.0: + resolution: {integrity: sha512-pTMbcf3rWdtLiYGpmoTjHEpeY8seiy6sR+9nD7LOs8KfUbHE4lOUAprTRqRAcWSQ6MQpdX+YEsxShtGsINtPtw==} + + mhchemparser@4.2.1: + resolution: {integrity: sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-frontmatter@2.0.0: + resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} + + 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-extension-math@3.1.0: + resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + 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-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + 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-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + 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==} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + mj-context-menu@0.6.1: + resolution: {integrity: sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.13: + resolution: {integrity: sha512-sPdqC6ByMVVGvF1ynvvMo0/o+oD1VX7DaHhijt1bFgjvBkHBib4t49GoNDhf2NDta4oeUNlaGbSt5K7qjZ955Q==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + + next@15.5.19: + resolution: {integrity: sha512-xNOW6tYshGX1/Oi3F8uuk4gpDeWsSUE/1Z0G5uUMekIxaQ0xc03UXd9II0VQHYMWviMeA0OHpJFAKsHf8bTYVg==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + nextra-theme-docs@3.3.1: + resolution: {integrity: sha512-P305m2UcW2IDyQhjrcAu0qpdPArikofinABslUCAyixYShsmcdDRUhIMd4QBHYru4gQuVjGWX9PhWZZCbNvzDQ==} + peerDependencies: + next: '>=13' + nextra: 3.3.1 + react: '>=18' + react-dom: '>=18' + + nextra@3.3.1: + resolution: {integrity: sha512-jiwj+LfUPHHeAxJAEqFuglxnbjFgzAOnDWFsjv7iv3BWiX8OksDwd3I2Sv3j2zba00iIBDEPdNeylfzTtTLZVg==} + engines: {node: '>=18'} + peerDependencies: + next: '>=13' + react: '>=18' + react-dom: '>=18' + + nlcst-to-string@4.0.0: + resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + npm-to-yarn@3.0.1: + resolution: {integrity: sha512-tt6PvKu4WyzPwWUzy/hvPFqn+uwXO0K1ZHka8az3NnrhWJDmSqI8ncWq0fkL0k/lmmi5tAC11FXwXuh0rFbt1A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + oniguruma-to-es@2.3.0: + resolution: {integrity: sha512-bwALDxriqfKGfUufKGGepCzu9x7nJQuoRoAFp4AnwehhC2crqrDIAP/uN2qdlsAvSMpeRC3+Yzhqc7hLmle5+g==} + + p-limit@6.2.0: + resolution: {integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==} + engines: {node: '>=18'} + + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-latin@7.0.0: + resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} + + parse-numeric-range@1.3.0: + resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + path-data-parser@0.1.0: + resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + points-on-curve@0.2.0: + resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} + + points-on-path@0.2.1: + resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} + + postcss@8.5.15: + resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} + engines: {node: ^10 || ^12 || >=14} + + property-information@7.2.0: + resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==} + + react-aria@3.50.0: + resolution: {integrity: sha512-S0Os6QZk33fzUAKu1QLT9afoUaCBt1ZNdoiq0n2YMVgKIdNIQS8zxiZ8O9hYE6QyDkHKjD6q39LQZ+qaSAIgjw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-medium-image-zoom@5.4.8: + resolution: {integrity: sha512-72CIldEUaPejjcaDOYIeDsGlWzNKpmxyKgiPi1LBCkWCIGHDLlA2KTeo2uNtmN/m72Y3k/2uWDfon9SDiPbHaA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + react-stately@3.48.0: + resolution: {integrity: sha512-ImicSAG+lTotAe5izcs1fz49Zk48w7pDusqYg04WaPhCoej8BJ24soMu3iLXIrsi273s4P1gZrYGrqReMfgEEA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + reading-time@1.5.0: + resolution: {integrity: sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + + regex-recursion@5.1.1: + resolution: {integrity: sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@5.1.1: + resolution: {integrity: sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw==} + + rehype-katex@7.0.1: + resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==} + + rehype-parse@9.0.1: + resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} + + rehype-pretty-code@0.14.0: + resolution: {integrity: sha512-hBeKF/Wkkf3zyUS8lal9RCUuhypDWLQc+h9UrP9Pav25FUm/AQAVh4m5gdvJxh4Oz+U+xKvdsV01p1LdvsZTiQ==} + engines: {node: '>=18'} + peerDependencies: + shiki: ^1.3.0 + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + remark-frontmatter@5.0.0: + resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-math@6.0.0: + resolution: {integrity: sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-reading-time@2.1.0: + resolution: {integrity: sha512-gBsJbQv87TUq4dRMSOgIX6P60Tk9ke8c29KsL7bccmsv2m9AycDfVu3ghRtrNpHLZU3TE5P/vImGOMSPzYU8rA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-smartypants@3.0.2: + resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} + engines: {node: '>=16.0.0'} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + retext-latin@4.0.0: + resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} + + retext-smartypants@6.2.0: + resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} + + retext-stringify@4.0.0: + resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} + + retext@9.0.0: + resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} + + robust-predicates@3.0.3: + resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} + + roughjs@4.6.6: + resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} + + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + scroll-into-view-if-needed@3.1.0: + resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} + + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + + semver@7.8.4: + resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} + engines: {node: '>=10'} + hasBin: true + + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shiki@1.29.2: + resolution: {integrity: sha512-njXuliz/cP+67jU2hukkxCNuH1yUi4QfdZZY+sMr5PPrIyXSu5iTb/qYC4BiWWB0vZ+7TbdvYUCeL23zpwCfbg==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + speech-rule-engine@4.1.4: + resolution: {integrity: sha512-i/VCLG1fvRc95pMHRqG4aQNscv+9aIsqA2oI7ZQS51sTdUcDHYX6cpT8/tqZ+enjs1tKVwbRBWgxut9SWn+f9g==} + hasBin: true + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + stylis@4.4.0: + resolution: {integrity: sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==} + + system-architecture@0.1.0: + resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==} + engines: {node: '>=18'} + + tabbable@6.4.0: + resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} + + tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} + engines: {node: '>=18'} + + title@4.0.1: + resolution: {integrity: sha512-xRnPkJx9nvE5MF6LkB5e8QJjE2FW8269wTu/LQdf7zZqBgPly0QJPf/CWAo7srj5so4yXfoLEdCFgurlpi47zg==} + hasBin: true + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-dedent@2.3.0: + resolution: {integrity: sha512-JfJeIHke7y2egdGGgRAvpCwYFUsHlM2gPcrVOxFkznt/4uzQ7HFmvE63iFHVLBJNDuyDOQgijDK/tXH/f6Msjg==} + engines: {node: '>=6.10'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + twoslash-protocol@0.2.12: + resolution: {integrity: sha512-5qZLXVYfZ9ABdjqbvPc4RWMr7PrpPaaDSeaYY55vl/w1j6H6kzsWK/urAEIXlzYlyrFmyz1UbwIt+AA0ck+wbg==} + + twoslash@0.2.12: + resolution: {integrity: sha512-tEHPASMqi7kqwfJbkk7hc/4EhlrKCSLcur+TcvYki3vhIfaRMXnXjaYFgXpoZRbT6GdprD4tGuVBEmTpUgLBsw==} + peerDependencies: + typescript: '*' + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + 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-modify-children@4.0.0: + resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-remove-position@5.0.0: + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + + unist-util-remove@4.0.0: + resolution: {integrity: sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-children@3.0.0: + resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} + + 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==} + + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + uuid@14.0.0: + resolution: {integrity: sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==} + hasBin: true + + 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==} + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wicked-good-xpath@1.3.0: + resolution: {integrity: sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw==} + + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} + engines: {node: '>= 14.6'} + hasBin: true + + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + + zod-validation-error@3.5.4: + resolution: {integrity: sha512-+hEiRIiPobgyuFlEojnqjJnhFvg4r/i3cqgcm67eehZf/WBaK3g6cD02YU9mtdVxZjv8CzCA9n/Rhrs3yAAvAw==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.24.4 + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.6.0 + tinyexec: 1.2.4 + + '@braintree/sanitize-url@7.1.2': {} + + '@chevrotain/types@11.1.2': {} + + '@emnapi/runtime@1.11.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@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/react-dom@2.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/dom': 1.7.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@floating-ui/react@0.26.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react-dom': 2.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@floating-ui/utils': 0.2.11 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tabbable: 6.4.0 + + '@floating-ui/utils@0.2.11': {} + + '@formatjs/intl-localematcher@0.5.10': + dependencies: + tslib: 2.8.1 + + '@headlessui/react@2.2.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react': 0.26.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@react-aria/focus': 3.22.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@react-aria/interactions': 3.28.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@tanstack/react-virtual': 3.14.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + use-sync-external-store: 1.6.0(react@18.3.1) + + '@iconify/types@2.0.0': {} + + '@iconify/utils@3.1.3': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@iconify/types': 2.0.0 + import-meta-resolve: 4.2.0 + + '@img/colour@1.1.0': + optional: true + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.11.1 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + + '@internationalized/date@3.12.2': + dependencies: + '@swc/helpers': 0.5.23 + + '@internationalized/number@3.6.7': + dependencies: + '@swc/helpers': 0.5.23 + + '@internationalized/string@3.2.9': + dependencies: + '@swc/helpers': 0.5.23 + + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.9 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.14 + acorn: 8.17.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.17.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@mdx-js/react@3.1.1(@types/react@19.2.17)(react@18.3.1)': + dependencies: + '@types/mdx': 2.0.14 + '@types/react': 19.2.17 + react: 18.3.1 + + '@mermaid-js/parser@1.1.1': + dependencies: + '@chevrotain/types': 11.1.2 + + '@napi-rs/simple-git-android-arm-eabi@0.1.22': + optional: true + + '@napi-rs/simple-git-android-arm64@0.1.22': + optional: true + + '@napi-rs/simple-git-darwin-arm64@0.1.22': + optional: true + + '@napi-rs/simple-git-darwin-x64@0.1.22': + optional: true + + '@napi-rs/simple-git-freebsd-x64@0.1.22': + optional: true + + '@napi-rs/simple-git-linux-arm-gnueabihf@0.1.22': + optional: true + + '@napi-rs/simple-git-linux-arm64-gnu@0.1.22': + optional: true + + '@napi-rs/simple-git-linux-arm64-musl@0.1.22': + optional: true + + '@napi-rs/simple-git-linux-ppc64-gnu@0.1.22': + optional: true + + '@napi-rs/simple-git-linux-s390x-gnu@0.1.22': + optional: true + + '@napi-rs/simple-git-linux-x64-gnu@0.1.22': + optional: true + + '@napi-rs/simple-git-linux-x64-musl@0.1.22': + optional: true + + '@napi-rs/simple-git-win32-arm64-msvc@0.1.22': + optional: true + + '@napi-rs/simple-git-win32-ia32-msvc@0.1.22': + optional: true + + '@napi-rs/simple-git-win32-x64-msvc@0.1.22': + optional: true + + '@napi-rs/simple-git@0.1.22': + optionalDependencies: + '@napi-rs/simple-git-android-arm-eabi': 0.1.22 + '@napi-rs/simple-git-android-arm64': 0.1.22 + '@napi-rs/simple-git-darwin-arm64': 0.1.22 + '@napi-rs/simple-git-darwin-x64': 0.1.22 + '@napi-rs/simple-git-freebsd-x64': 0.1.22 + '@napi-rs/simple-git-linux-arm-gnueabihf': 0.1.22 + '@napi-rs/simple-git-linux-arm64-gnu': 0.1.22 + '@napi-rs/simple-git-linux-arm64-musl': 0.1.22 + '@napi-rs/simple-git-linux-ppc64-gnu': 0.1.22 + '@napi-rs/simple-git-linux-s390x-gnu': 0.1.22 + '@napi-rs/simple-git-linux-x64-gnu': 0.1.22 + '@napi-rs/simple-git-linux-x64-musl': 0.1.22 + '@napi-rs/simple-git-win32-arm64-msvc': 0.1.22 + '@napi-rs/simple-git-win32-ia32-msvc': 0.1.22 + '@napi-rs/simple-git-win32-x64-msvc': 0.1.22 + + '@next/env@15.5.19': {} + + '@next/swc-darwin-arm64@15.5.19': + optional: true + + '@next/swc-darwin-x64@15.5.19': + optional: true + + '@next/swc-linux-arm64-gnu@15.5.19': + optional: true + + '@next/swc-linux-arm64-musl@15.5.19': + optional: true + + '@next/swc-linux-x64-gnu@15.5.19': + optional: true + + '@next/swc-linux-x64-musl@15.5.19': + optional: true + + '@next/swc-win32-arm64-msvc@15.5.19': + optional: true + + '@next/swc-win32-x64-msvc@15.5.19': + optional: true + + '@react-aria/focus@3.22.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@swc/helpers': 0.5.23 + react: 18.3.1 + react-aria: 3.50.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-dom: 18.3.1(react@18.3.1) + + '@react-aria/interactions@3.28.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@react-types/shared': 3.36.0(react@18.3.1) + '@swc/helpers': 0.5.23 + react: 18.3.1 + react-aria: 3.50.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-dom: 18.3.1(react@18.3.1) + + '@react-types/shared@3.36.0(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@shikijs/core@1.29.2': + dependencies: + '@shikijs/engine-javascript': 1.29.2 + '@shikijs/engine-oniguruma': 1.29.2 + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 2.3.0 + + '@shikijs/engine-oniguruma@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + + '@shikijs/themes@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + + '@shikijs/twoslash@1.29.2(typescript@6.0.3)': + dependencies: + '@shikijs/core': 1.29.2 + '@shikijs/types': 1.29.2 + twoslash: 0.2.12(typescript@6.0.3) + transitivePeerDependencies: + - supports-color + - typescript + + '@shikijs/types@1.29.2': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@swc/helpers@0.5.23': + dependencies: + tslib: 2.8.1 + + '@tanstack/react-virtual@3.14.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@tanstack/virtual-core': 3.17.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@tanstack/virtual-core@3.17.1': {} + + '@theguild/remark-mermaid@0.1.3(react@18.3.1)': + dependencies: + mermaid: 11.15.0 + react: 18.3.1 + unist-util-visit: 5.1.0 + + '@theguild/remark-npm2yarn@0.3.3': + dependencies: + npm-to-yarn: 3.0.1 + unist-util-visit: 5.1.0 + + '@types/d3-array@3.2.2': {} + + '@types/d3-axis@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-brush@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-chord@3.0.6': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-contour@3.0.6': + dependencies: + '@types/d3-array': 3.2.2 + '@types/geojson': 7946.0.16 + + '@types/d3-delaunay@6.0.4': {} + + '@types/d3-dispatch@3.0.7': {} + + '@types/d3-drag@3.0.7': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-dsv@3.0.7': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-fetch@3.0.7': + dependencies: + '@types/d3-dsv': 3.0.7 + + '@types/d3-force@3.0.10': {} + + '@types/d3-format@3.0.4': {} + + '@types/d3-geo@3.1.0': + dependencies: + '@types/geojson': 7946.0.16 + + '@types/d3-hierarchy@3.1.7': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.1': {} + + '@types/d3-polygon@3.0.2': {} + + '@types/d3-quadtree@3.0.6': {} + + '@types/d3-random@3.0.3': {} + + '@types/d3-scale-chromatic@3.1.0': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-selection@3.0.11': {} + + '@types/d3-shape@3.1.8': + dependencies: + '@types/d3-path': 3.1.1 + + '@types/d3-time-format@4.0.3': {} + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + + '@types/d3-transition@3.0.9': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-zoom@3.0.8': + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + + '@types/d3@7.4.3': + dependencies: + '@types/d3-array': 3.2.2 + '@types/d3-axis': 3.0.6 + '@types/d3-brush': 3.0.6 + '@types/d3-chord': 3.0.6 + '@types/d3-color': 3.1.3 + '@types/d3-contour': 3.0.6 + '@types/d3-delaunay': 6.0.4 + '@types/d3-dispatch': 3.0.7 + '@types/d3-drag': 3.0.7 + '@types/d3-dsv': 3.0.7 + '@types/d3-ease': 3.0.2 + '@types/d3-fetch': 3.0.7 + '@types/d3-force': 3.0.10 + '@types/d3-format': 3.0.4 + '@types/d3-geo': 3.1.0 + '@types/d3-hierarchy': 3.1.7 + '@types/d3-interpolate': 3.0.4 + '@types/d3-path': 3.1.1 + '@types/d3-polygon': 3.0.2 + '@types/d3-quadtree': 3.0.6 + '@types/d3-random': 3.0.3 + '@types/d3-scale': 4.0.9 + '@types/d3-scale-chromatic': 3.1.0 + '@types/d3-selection': 3.0.11 + '@types/d3-shape': 3.1.8 + '@types/d3-time': 3.0.4 + '@types/d3-time-format': 4.0.3 + '@types/d3-timer': 3.0.2 + '@types/d3-transition': 3.0.9 + '@types/d3-zoom': 3.0.8 + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.9 + + '@types/estree@1.0.9': {} + + '@types/geojson@7946.0.16': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/katex@0.16.8': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.14': {} + + '@types/ms@2.1.0': {} + + '@types/nlcst@2.0.3': + dependencies: + '@types/unist': 3.0.3 + + '@types/react@19.2.17': + dependencies: + csstype: 3.2.3 + + '@types/trusted-types@2.0.7': + optional: true + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@typescript/vfs@1.6.4(typescript@6.0.3)': + dependencies: + debug: 4.4.3 + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@ungap/structured-clone@1.3.1': {} + + '@upsetjs/venn.js@2.0.0': + optionalDependencies: + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + '@xmldom/xmldom@0.9.10': {} + + acorn-jsx@5.3.2(acorn@8.17.0): + dependencies: + acorn: 8.17.0 + + acorn@8.17.0: {} + + arg@5.0.2: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + + array-iterate@2.0.1: {} + + astring@1.9.0: {} + + bail@2.0.2: {} + + better-react-mathjax@2.3.0(react@18.3.1): + dependencies: + mathjax-full: 3.2.2 + react: 18.3.1 + + caniuse-lite@1.0.30001799: {} + + 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: {} + + character-reference-invalid@2.0.1: {} + + client-only@0.0.1: {} + + clipboardy@4.0.0: + dependencies: + execa: 8.0.1 + is-wsl: 3.1.1 + is64bit: 2.0.0 + + clsx@2.1.1: {} + + collapse-white-space@2.1.0: {} + + comma-separated-tokens@2.0.3: {} + + commander@13.1.0: {} + + commander@7.2.0: {} + + commander@8.3.0: {} + + compute-scroll-into-view@3.1.1: {} + + cose-base@1.0.3: + dependencies: + layout-base: 1.0.2 + + cose-base@2.2.0: + dependencies: + layout-base: 2.0.1 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.2.3: {} + + cytoscape-cose-bilkent@4.1.0(cytoscape@3.34.0): + dependencies: + cose-base: 1.0.3 + cytoscape: 3.34.0 + + cytoscape-fcose@2.2.0(cytoscape@3.34.0): + dependencies: + cose-base: 2.2.0 + cytoscape: 3.34.0 + + cytoscape@3.34.0: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + + d3-color@3.1.0: {} + + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.1.0 + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.2: {} + + d3-geo@3.1.1: + dependencies: + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.2 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.2 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + + dagre-d3-es@7.0.14: + dependencies: + d3: 7.9.0 + lodash-es: 4.18.1 + + dayjs@1.11.21: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + delaunator@5.1.0: + dependencies: + robust-predicates: 3.0.3 + + dequal@2.0.3: {} + + detect-libc@2.1.2: + optional: true + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + dompurify@3.4.11: + optionalDependencies: + '@types/trusted-types': 2.0.7 + + emoji-regex-xs@1.0.0: {} + + entities@6.0.1: {} + + es-toolkit@1.47.1: {} + + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.17.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + + escape-string-regexp@5.0.0: {} + + esm@3.2.25: {} + + esprima@4.0.1: {} + + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.9 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.9 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-value-to-estree@3.5.0: + dependencies: + '@types/estree': 1.0.9 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.9 + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend@3.0.2: {} + + fault@2.0.1: + dependencies: + format: 0.2.2 + + flexsearch@0.7.43: {} + + format@0.2.2: {} + + get-stream@8.0.1: {} + + github-slugger@2.0.0: {} + + graceful-fs@4.2.11: {} + + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.2 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + + hachure-fill@0.5.2: {} + + hast-util-from-dom@5.0.1: + dependencies: + '@types/hast': 3.0.4 + hastscript: 9.0.1 + web-namespaces: 2.0.1 + + hast-util-from-html-isomorphic@2.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-dom: 5.0.1 + hast-util-from-html: 2.0.3 + unist-util-remove-position: 5.0.0 + + 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.2.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-is-element@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + 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-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.9 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + 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.2.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.9 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + 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.2.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.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.2.0 + space-separated-tokens: 2.0.2 + + html-void-elements@3.0.0: {} + + human-signals@5.0.0: {} + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + import-meta-resolve@4.2.0: {} + + inline-style-parser@0.2.7: {} + + internmap@1.0.1: {} + + internmap@2.0.3: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-decimal@2.0.1: {} + + is-docker@3.0.0: {} + + is-extendable@0.1.1: {} + + is-hexadecimal@2.0.1: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-plain-obj@4.1.0: {} + + is-stream@3.0.0: {} + + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + + is64bit@2.0.0: + dependencies: + system-architecture: 0.1.0 + + isexe@2.0.0: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + katex@0.16.47: + dependencies: + commander: 8.3.0 + + khroma@2.1.0: {} + + kind-of@6.0.3: {} + + layout-base@1.0.2: {} + + layout-base@2.0.1: {} + + lodash-es@4.18.1: {} + + longest-streak@3.1.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + markdown-extensions@2.0.0: {} + + markdown-table@3.0.4: {} + + marked@16.4.2: {} + + mathjax-full@3.2.2: + dependencies: + esm: 3.2.25 + mhchemparser: 4.2.1 + mj-context-menu: 0.6.1 + speech-rule-engine: 4.1.4 + + 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-frontmatter@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + escape-string-regexp: 5.0.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-extension-frontmatter: 2.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-math@3.0.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + longest-streak: 3.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + unist-util-remove-position: 5.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@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-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@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-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 + + merge-stream@2.0.0: {} + + mermaid@11.15.0: + dependencies: + '@braintree/sanitize-url': 7.1.2 + '@iconify/utils': 3.1.3 + '@mermaid-js/parser': 1.1.1 + '@types/d3': 7.4.3 + '@upsetjs/venn.js': 2.0.0 + cytoscape: 3.34.0 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.34.0) + cytoscape-fcose: 2.2.0(cytoscape@3.34.0) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.14 + dayjs: 1.11.21 + dompurify: 3.4.11 + es-toolkit: 1.47.1 + katex: 0.16.47 + khroma: 2.1.0 + marked: 16.4.2 + roughjs: 4.6.6 + stylis: 4.4.0 + ts-dedent: 2.3.0 + uuid: 14.0.0 + + mhchemparser@4.2.1: {} + + 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-frontmatter@2.0.0: + dependencies: + fault: 2.0.1 + micromark-util-character: 2.1.1 + 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-extension-math@3.1.0: + dependencies: + '@types/katex': 0.16.8 + devlop: 1.1.0 + katex: 0.16.47 + 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-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.9 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.9 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.9 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.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-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.9 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + 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-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.9 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + 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 + + mimic-fn@4.0.0: {} + + mj-context-menu@0.6.1: {} + + ms@2.1.3: {} + + nanoid@3.3.13: {} + + negotiator@1.0.0: {} + + next-themes@0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + next@15.5.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@next/env': 15.5.19 + '@swc/helpers': 0.5.15 + caniuse-lite: 1.0.30001799 + postcss: 8.5.15 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.6(react@18.3.1) + optionalDependencies: + '@next/swc-darwin-arm64': 15.5.19 + '@next/swc-darwin-x64': 15.5.19 + '@next/swc-linux-arm64-gnu': 15.5.19 + '@next/swc-linux-arm64-musl': 15.5.19 + '@next/swc-linux-x64-gnu': 15.5.19 + '@next/swc-linux-x64-musl': 15.5.19 + '@next/swc-win32-arm64-msvc': 15.5.19 + '@next/swc-win32-x64-msvc': 15.5.19 + sharp: 0.34.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + nextra-theme-docs@3.3.1(next@15.5.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@3.3.1(@types/react@19.2.17)(next@15.5.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@6.0.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@headlessui/react': 2.2.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + clsx: 2.1.1 + escape-string-regexp: 5.0.0 + flexsearch: 0.7.43 + next: 15.5.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next-themes: 0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + nextra: 3.3.1(@types/react@19.2.17)(next@15.5.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@6.0.3) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + scroll-into-view-if-needed: 3.1.0 + zod: 3.25.76 + + nextra@3.3.1(@types/react@19.2.17)(next@15.5.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@6.0.3): + dependencies: + '@formatjs/intl-localematcher': 0.5.10 + '@headlessui/react': 2.2.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mdx-js/mdx': 3.1.1 + '@mdx-js/react': 3.1.1(@types/react@19.2.17)(react@18.3.1) + '@napi-rs/simple-git': 0.1.22 + '@shikijs/twoslash': 1.29.2(typescript@6.0.3) + '@theguild/remark-mermaid': 0.1.3(react@18.3.1) + '@theguild/remark-npm2yarn': 0.3.3 + better-react-mathjax: 2.3.0(react@18.3.1) + clsx: 2.1.1 + estree-util-to-js: 2.0.0 + estree-util-value-to-estree: 3.5.0 + github-slugger: 2.0.0 + graceful-fs: 4.2.11 + gray-matter: 4.0.3 + hast-util-to-estree: 3.1.3 + katex: 0.16.47 + mdast-util-from-markdown: 2.0.3 + mdast-util-gfm: 3.1.0 + mdast-util-to-hast: 13.2.1 + negotiator: 1.0.0 + next: 15.5.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + p-limit: 6.2.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-medium-image-zoom: 5.4.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rehype-katex: 7.0.1 + rehype-pretty-code: 0.14.0(shiki@1.29.2) + rehype-raw: 7.0.0 + remark-frontmatter: 5.0.0 + remark-gfm: 4.0.1 + remark-math: 6.0.0 + remark-reading-time: 2.1.0 + remark-smartypants: 3.0.2 + shiki: 1.29.2 + slash: 5.1.0 + title: 4.0.1 + unist-util-remove: 4.0.0 + unist-util-visit: 5.1.0 + yaml: 2.9.0 + zod: 3.25.76 + zod-validation-error: 3.5.4(zod@3.25.76) + transitivePeerDependencies: + - '@types/react' + - supports-color + - typescript + + nlcst-to-string@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + npm-to-yarn@3.0.1: {} + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + oniguruma-to-es@2.3.0: + dependencies: + emoji-regex-xs: 1.0.0 + regex: 5.1.1 + regex-recursion: 5.1.1 + + p-limit@6.2.0: + dependencies: + yocto-queue: 1.2.2 + + package-manager-detector@1.6.0: {} + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse-latin@7.0.0: + dependencies: + '@types/nlcst': 2.0.3 + '@types/unist': 3.0.3 + nlcst-to-string: 4.0.0 + unist-util-modify-children: 4.0.0 + unist-util-visit-children: 3.0.0 + vfile: 6.0.3 + + parse-numeric-range@1.3.0: {} + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + path-data-parser@0.1.0: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + picocolors@1.1.1: {} + + points-on-curve@0.2.0: {} + + points-on-path@0.2.1: + dependencies: + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + + postcss@8.5.15: + dependencies: + nanoid: 3.3.13 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + property-information@7.2.0: {} + + react-aria@3.50.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@internationalized/date': 3.12.2 + '@internationalized/number': 3.6.7 + '@internationalized/string': 3.2.9 + '@react-types/shared': 3.36.0(react@18.3.1) + '@swc/helpers': 0.5.23 + aria-hidden: 1.2.6 + clsx: 2.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-stately: 3.48.0(react@18.3.1) + use-sync-external-store: 1.6.0(react@18.3.1) + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-medium-image-zoom@5.4.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + react-stately@3.48.0(react@18.3.1): + dependencies: + '@internationalized/date': 3.12.2 + '@internationalized/number': 3.6.7 + '@internationalized/string': 3.2.9 + '@react-types/shared': 3.36.0(react@18.3.1) + '@swc/helpers': 0.5.23 + react: 18.3.1 + use-sync-external-store: 1.6.0(react@18.3.1) + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + reading-time@1.5.0: {} + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.9 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.17.0): + dependencies: + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.9 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.9 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + + regex-recursion@5.1.1: + dependencies: + regex: 5.1.1 + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@5.1.1: + dependencies: + regex-utilities: 2.3.0 + + rehype-katex@7.0.1: + dependencies: + '@types/hast': 3.0.4 + '@types/katex': 0.16.8 + hast-util-from-html-isomorphic: 2.0.0 + hast-util-to-text: 4.0.2 + katex: 0.16.47 + unist-util-visit-parents: 6.0.2 + vfile: 6.0.3 + + rehype-parse@9.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-html: 2.0.3 + unified: 11.0.5 + + rehype-pretty-code@0.14.0(shiki@1.29.2): + dependencies: + '@types/hast': 3.0.4 + hast-util-to-string: 3.0.1 + parse-numeric-range: 1.3.0 + rehype-parse: 9.0.1 + shiki: 1.29.2 + unified: 11.0.5 + unist-util-visit: 5.1.0 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.9 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + remark-frontmatter@5.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-frontmatter: 2.0.1 + micromark-extension-frontmatter: 2.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + 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-math@6.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-math: 3.0.0 + micromark-extension-math: 3.1.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + 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-reading-time@2.1.0: + dependencies: + estree-util-is-identifier-name: 3.0.0 + estree-util-value-to-estree: 3.5.0 + reading-time: 1.5.0 + unist-util-visit: 5.1.0 + + 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-smartypants@3.0.2: + dependencies: + retext: 9.0.0 + retext-smartypants: 6.2.0 + unified: 11.0.5 + unist-util-visit: 5.1.0 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + retext-latin@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + parse-latin: 7.0.0 + unified: 11.0.5 + + retext-smartypants@6.2.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unist-util-visit: 5.1.0 + + retext-stringify@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unified: 11.0.5 + + retext@9.0.0: + dependencies: + '@types/nlcst': 2.0.3 + retext-latin: 4.0.0 + retext-stringify: 4.0.0 + unified: 11.0.5 + + robust-predicates@3.0.3: {} + + roughjs@4.6.6: + dependencies: + hachure-fill: 0.5.2 + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + points-on-path: 0.2.1 + + rw@1.3.3: {} + + safer-buffer@2.1.2: {} + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + scroll-into-view-if-needed@3.1.0: + dependencies: + compute-scroll-into-view: 3.1.1 + + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + + semver@7.8.4: + optional: true + + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.4 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + optional: true + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shiki@1.29.2: + dependencies: + '@shikijs/core': 1.29.2 + '@shikijs/engine-javascript': 1.29.2 + '@shikijs/engine-oniguruma': 1.29.2 + '@shikijs/langs': 1.29.2 + '@shikijs/themes': 1.29.2 + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + signal-exit@4.1.0: {} + + slash@5.1.0: {} + + source-map-js@1.2.1: {} + + source-map@0.7.6: {} + + space-separated-tokens@2.0.2: {} + + speech-rule-engine@4.1.4: + dependencies: + '@xmldom/xmldom': 0.9.10 + commander: 13.1.0 + wicked-good-xpath: 1.3.0 + + sprintf-js@1.0.3: {} + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-bom-string@1.0.0: {} + + strip-final-newline@3.0.0: {} + + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + + styled-jsx@5.1.6(react@18.3.1): + dependencies: + client-only: 0.0.1 + react: 18.3.1 + + stylis@4.4.0: {} + + system-architecture@0.1.0: {} + + tabbable@6.4.0: {} + + tinyexec@1.2.4: {} + + title@4.0.1: + dependencies: + arg: 5.0.2 + chalk: 5.6.2 + clipboardy: 4.0.0 + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + ts-dedent@2.3.0: {} + + tslib@2.8.1: {} + + twoslash-protocol@0.2.12: {} + + twoslash@0.2.12(typescript@6.0.3): + dependencies: + '@typescript/vfs': 1.6.4(typescript@6.0.3) + twoslash-protocol: 0.2.12 + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + typescript@6.0.3: {} + + 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-modify-children@4.0.0: + dependencies: + '@types/unist': 3.0.3 + array-iterate: 2.0.1 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-remove-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-visit: 5.1.0 + + unist-util-remove@4.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-children@3.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 + + use-sync-external-store@1.6.0(react@18.3.1): + dependencies: + react: 18.3.1 + + uuid@14.0.0: {} + + 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 + + web-namespaces@2.0.1: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wicked-good-xpath@1.3.0: {} + + yaml@2.9.0: {} + + yocto-queue@1.2.2: {} + + zod-validation-error@3.5.4(zod@3.25.76): + dependencies: + zod: 3.25.76 + + zod@3.25.76: {} + + zwitch@2.0.4: {} diff --git a/website/public/favicon.svg b/website/public/favicon.svg new file mode 100644 index 0000000..6d8e21c --- /dev/null +++ b/website/public/favicon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/website/public/robots.txt b/website/public/robots.txt new file mode 100644 index 0000000..b9907e3 --- /dev/null +++ b/website/public/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://androidpoet.github.io/revenuecat-cli/sitemap.xml diff --git a/website/styles/globals.css b/website/styles/globals.css new file mode 100644 index 0000000..88e71f6 --- /dev/null +++ b/website/styles/globals.css @@ -0,0 +1,157 @@ +/* ---- Entrance animations ---- */ +@keyframes rc-fade-up { + from { + opacity: 0; + transform: translateY(18px); + } + to { + opacity: 1; + transform: none; + } +} + +@keyframes rc-gradient { + 0%, + 100% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } +} + +@keyframes rc-float { + 0%, + 100% { + transform: translate(-50%, 0) scale(1); + opacity: 0.55; + } + 50% { + transform: translate(-50%, -18px) scale(1.08); + opacity: 0.8; + } +} + +/* ---- Hero ---- */ +.rc-hero { + position: relative; + text-align: center; + padding: 4.5rem 1rem 3rem; + overflow: hidden; +} + +.rc-hero-glow { + position: absolute; + top: -40%; + left: 50%; + width: min(720px, 90%); + height: 420px; + transform: translateX(-50%); + background: radial-gradient( + closest-side, + rgba(75, 72, 242, 0.4), + rgba(75, 72, 242, 0) 70% + ); + filter: blur(8px); + z-index: -1; + animation: rc-float 9s ease-in-out infinite; + pointer-events: none; +} + +.rc-hero-badge { + display: inline-block; + font-size: 0.78rem; + font-weight: 600; + letter-spacing: 0.02em; + padding: 0.3rem 0.75rem; + border-radius: 999px; + color: #4b48f2; + background: rgba(75, 72, 242, 0.12); + border: 1px solid rgba(75, 72, 242, 0.3); + animation: rc-fade-up 0.5s ease both; +} + +.rc-hero-title { + font-size: clamp(2.75rem, 7vw, 4.5rem); + font-weight: 800; + line-height: 1.05; + margin: 1.25rem 0 0; + letter-spacing: -0.03em; + background: linear-gradient(110deg, #4b48f2, #7d5cff, #e8514a, #4b48f2); + background-size: 250% 250%; + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + animation: rc-fade-up 0.6s ease both 0.05s, rc-gradient 8s ease infinite; +} + +.rc-hero-sub { + max-width: 38rem; + margin: 1.1rem auto 0; + font-size: clamp(1rem, 2.2vw, 1.18rem); + line-height: 1.6; + color: var(--nextra-fg, #6b7280); + opacity: 0.9; + animation: rc-fade-up 0.6s ease both 0.15s; +} + +.rc-hero-cta { + display: flex; + gap: 0.75rem; + justify-content: center; + flex-wrap: wrap; + margin-top: 2rem; + animation: rc-fade-up 0.6s ease both 0.25s; +} + +.rc-btn { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.7rem 1.4rem; + border-radius: 0.6rem; + font-weight: 600; + font-size: 0.95rem; + text-decoration: none !important; + transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease; +} + +.rc-btn:hover { + transform: translateY(-2px); +} + +.rc-btn-primary { + color: #ffffff !important; + background: linear-gradient(120deg, #4b48f2, #3a37d8); + box-shadow: 0 6px 20px -6px rgba(75, 72, 242, 0.7); +} + +.rc-btn-primary:hover { + box-shadow: 0 10px 28px -6px rgba(75, 72, 242, 0.8); +} + +.rc-btn-ghost { + color: inherit !important; + border: 1px solid var(--nextra-border, rgba(125, 125, 125, 0.3)); + background: transparent; +} + +.rc-btn-ghost:hover { + background: rgba(125, 125, 125, 0.08); +} + +/* ---- Code block polish ---- */ +.nextra-code pre { + border-radius: 0.7rem !important; + box-shadow: 0 4px 18px -10px rgba(0, 0, 0, 0.5); + transition: box-shadow 0.2s ease; +} + +.nextra-code:hover pre { + box-shadow: 0 8px 26px -10px rgba(75, 72, 242, 0.45); +} + +/* Fade content cards in as the page mounts */ +.nextra-content .nextra-cards { + animation: rc-fade-up 0.5s ease both 0.1s; +} diff --git a/website/theme.config.jsx b/website/theme.config.jsx new file mode 100644 index 0000000..c275be1 --- /dev/null +++ b/website/theme.config.jsx @@ -0,0 +1,85 @@ +import { useConfig } from 'nextra-theme-docs' +import { useRouter } from 'next/router' + +const Logo = () => ( + + + RevenueCat CLI + +) + +export default { + logo: , + project: { + link: 'https://github.com/AndroidPoet/revenuecat-cli', + }, + docsRepositoryBase: 'https://github.com/AndroidPoet/revenuecat-cli/tree/master/website', + color: { + hue: 242, + saturation: 88, + }, + footer: { + content: ( + + MIT © {new Date().getFullYear()}{' '} + + RevenueCat CLI + + . Manage subscriptions from your terminal. + + ), + }, + head: function useHead() { + const { frontMatter } = useConfig() + const { asPath } = useRouter() + const pageTitle = frontMatter?.title + const title = pageTitle ? `${pageTitle} – RevenueCat CLI` : 'RevenueCat CLI' + const description = + frontMatter?.description ?? + 'RevenueCat CLI — a fast, scriptable command-line tool for managing RevenueCat: subscriptions, products, offerings, charts, and reports, with JSON-first output built for CI/CD.' + const base = 'https://androidpoet.github.io/revenuecat-cli' + const path = asPath === '/' ? '' : asPath.split('?')[0].split('#')[0] + const canonical = `${base}${path}` + const ogImage = `${base}/favicon.svg` + return ( + <> + + {title} + + + + + + + + + + + + + + + + ) + }, + sidebar: { + defaultMenuCollapseLevel: 1, + }, + toc: { + backToTop: true, + }, + navigation: { + prev: true, + next: true, + }, + darkMode: true, +}