diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 82a0e8c5..ffe4e44c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,6 @@ jobs: online-feature-store-changed: ${{ steps.changes.outputs.online-feature-store }} go-sdk-changed: ${{ steps.changes.outputs.go-sdk }} py-sdk-changed: ${{ steps.changes.outputs.py-sdk }} - helix-client-changed: ${{ steps.changes.outputs.helix-client }} inferflow-changed: ${{ steps.changes.outputs.inferflow }} skye-changed: ${{ steps.changes.outputs.skye }} multiple-components: ${{ steps.check-multiple.outputs.multiple }} @@ -48,8 +47,6 @@ jobs: - 'go-sdk/**' py-sdk: - 'py-sdk/**' - helix-client: - - 'helix-client/**' inferflow: - 'inferflow/**' skye: @@ -77,9 +74,6 @@ jobs: if [ "${{ steps.changes.outputs.py-sdk }}" == "true" ]; then changed_count=$((changed_count + 1)) fi - if [ "${{ steps.changes.outputs.helix-client }}" == "true" ]; then - changed_count=$((changed_count + 1)) - fi if [ "${{ steps.changes.outputs.inferflow }}" == "true" ]; then changed_count=$((changed_count + 1)) fi @@ -96,7 +90,7 @@ jobs: - name: Check if any component changed id: check-any run: | - if [ "${{ steps.changes.outputs.horizon }}" == "true" ] || [ "${{ steps.changes.outputs.trufflebox-ui }}" == "true" ] || [ "${{ steps.changes.outputs.numerix }}" == "true" ] || [ "${{ steps.changes.outputs.online-feature-store }}" == "true" ] || [ "${{ steps.changes.outputs.go-sdk }}" == "true" ] || [ "${{ steps.changes.outputs.py-sdk }}" == "true" ] || [ "${{ steps.changes.outputs.helix-client }}" == "true" ] || [ "${{ steps.changes.outputs.inferflow }}" == "true" ] || [ "${{ steps.changes.outputs.skye }}" == "true" ]; then + if [ "${{ steps.changes.outputs.horizon }}" == "true" ] || [ "${{ steps.changes.outputs.trufflebox-ui }}" == "true" ] || [ "${{ steps.changes.outputs.numerix }}" == "true" ] || [ "${{ steps.changes.outputs.online-feature-store }}" == "true" ] || [ "${{ steps.changes.outputs.go-sdk }}" == "true" ] || [ "${{ steps.changes.outputs.py-sdk }}" == "true" ] || [ "${{ steps.changes.outputs.inferflow }}" == "true" ] || [ "${{ steps.changes.outputs.skye }}" == "true" ]; then echo "any=true" >> $GITHUB_OUTPUT else echo "any=false" >> $GITHUB_OUTPUT @@ -116,7 +110,6 @@ jobs: echo "- Online Feature Store CI: ${{ needs.detect-changes.outputs.online-feature-store-changed }}" echo "- Go SDK CI: ${{ needs.detect-changes.outputs.go-sdk-changed }}" echo "- Python SDK CI: ${{ needs.detect-changes.outputs.py-sdk-changed }}" - echo "- Helix Client CI: ${{ needs.detect-changes.outputs.helix-client-changed }}" echo "- Inferflow CI: ${{ needs.detect-changes.outputs.inferflow-changed }}" echo "- Skye CI: ${{ needs.detect-changes.outputs.skye-changed }}" echo "This workflow will proceed with integration tests..." @@ -137,7 +130,6 @@ jobs: echo "Testing Numerix matrix operations integration..." echo "Testing Go SDK compatibility with backend services..." echo "Testing Python SDK compatibility with backend services..." - echo "Testing Helix Client compatibility with backend services..." echo "Testing Inferflow compatibility with backend services..." # Add actual integration test commands here @@ -218,6 +210,5 @@ jobs: echo "- Online Feature Store: ${{ needs.detect-changes.outputs.online-feature-store-changed }}" >> $GITHUB_STEP_SUMMARY echo "- Go SDK: ${{ needs.detect-changes.outputs.go-sdk-changed }}" >> $GITHUB_STEP_SUMMARY echo "- Python SDK: ${{ needs.detect-changes.outputs.py-sdk-changed }}" >> $GITHUB_STEP_SUMMARY - echo "- Helix Client: ${{ needs.detect-changes.outputs.helix-client-changed }}" >> $GITHUB_STEP_SUMMARY echo "- Inferflow: ${{ needs.detect-changes.outputs.inferflow-changed }}" >> $GITHUB_STEP_SUMMARY echo "- Skye: ${{ needs.detect-changes.outputs.skye-changed }}" >> $GITHUB_STEP_SUMMARY \ No newline at end of file diff --git a/.github/workflows/helix-client.yml b/.github/workflows/helix-client.yml deleted file mode 100644 index ff236ded..00000000 --- a/.github/workflows/helix-client.yml +++ /dev/null @@ -1,71 +0,0 @@ -name: Helix Client CI - -on: - pull_request: - branches: [main, develop] - paths: ['helix-client/**'] - push: - branches: [main, develop] - paths: ['helix-client/**'] - -jobs: - build-helix-client: - runs-on: ubuntu-latest - defaults: - run: - working-directory: ./helix-client - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v4 - with: - go-version: '1.24' - cache: false - - - name: Cache Go modules - uses: actions/cache@v3 - with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-helix-client-${{ hashFiles('helix-client/go.sum') }} - restore-keys: | - ${{ runner.os }}-helix-client- - - - name: Download dependencies - run: go mod download - - - name: Verify dependencies - run: go mod verify - - - name: Run tests - run: go test -v ./... - - - name: Run tests with coverage - run: go test -v -coverprofile=coverage.out ./... - - - name: Display coverage - run: go tool cover -func=coverage.out - - - name: Build SDK packages - run: go build -v ./... - - - name: Run go vet - run: go vet ./... - - - name: Install staticcheck - run: go install honnef.co/go/tools/cmd/staticcheck@latest - - - name: Run staticcheck - run: staticcheck ./... - - - name: Check for go mod tidy - run: | - go mod tidy - if [ -n "$(git status --porcelain go.mod go.sum)" ]; then - echo "go.mod or go.sum is not tidy" - git diff go.mod go.sum - exit 1 - fi \ No newline at end of file diff --git a/.github/workflows/release-helix-client.yml b/.github/workflows/release-helix-client.yml deleted file mode 100644 index 5ed33890..00000000 --- a/.github/workflows/release-helix-client.yml +++ /dev/null @@ -1,151 +0,0 @@ -name: Release Helix Client - -on: - workflow_dispatch: - inputs: - version: - description: 'Version to release (e.g., v0.1.20 or v0.1.20-beta.1)' - required: true - type: string - is_beta: - description: 'Is this a beta release?' - required: false - type: boolean - default: false - is_alpha: - description: 'Is this an alpha release?' - required: false - type: boolean - default: false - branch: - description: 'Branch to release from' - required: true - type: string - default: 'main' - -jobs: - release: - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - ref: ${{ inputs.branch }} - - - name: Set up Go - uses: actions/setup-go@v4 - with: - go-version: '1.24' - - - name: Validate Helix Client - run: | - echo "Current branch: ${{ github.ref }}" - cd helix-client - go mod tidy - go test -v ./... - go build -v ./... - go vet ./... - - - name: Create Git tag - run: | - git config --global user.name "github-actions[bot]" - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - - TAG="helix-client/${{ inputs.version }}" - git tag -a "$TAG" -m "Helix Client release ${{ inputs.version }}" - git push origin "$TAG" - - - name: Create GitHub Release (Production) - if: ${{ !inputs.is_beta && !inputs.is_alpha }} - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: helix-client/${{ inputs.version }} - release_name: Helix Client ${{ inputs.version }} - body: | - ## Helix Client Release ${{ inputs.version }} - - ### Installation - ```bash - go get github.com/${{ github.repository }}/helix-client@${{ inputs.version }} - ``` - - ### Features - - Go client libraries for BharatMLStack services - - Numerix, Predator, and Skye client integrations - - Type-safe API bindings and gRPC support - - ### Usage - ```go - import "github.com/${{ github.repository }}/helix-client" - ``` - - ### Changes - Please see the commit history for detailed changes. - - ### Validation - - ✅ Tests passed - - ✅ Build successful - - ✅ Go vet clean - draft: false - prerelease: false - - - name: Create Beta Pre-release - if: ${{ inputs.is_beta }} - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: helix-client/${{ inputs.version }} - release_name: Helix Client ${{ inputs.version }} (Beta) - body: | - ## Helix Client Beta Release ${{ inputs.version }} - - ⚠️ **This is a beta release from the develop branch** - Use for testing purposes only. - - ### Installation - ```bash - go get github.com/${{ github.repository }}/helix-client@${{ inputs.version }} - ``` - - ### Changes - Please see the commit history for detailed changes. - - ### Validation - - ✅ Tests passed - - ✅ Build successful - - ✅ Go vet clean - draft: false - prerelease: true - - - name: Create Alpha Pre-release - if: ${{ inputs.is_alpha }} - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: helix-client/${{ inputs.version }} - release_name: Helix Client ${{ inputs.version }} (Alpha) - body: | - ## Helix Client Alpha Release ${{ inputs.version }} - - ⚠️ **This is an alpha release from a feature/fix branch** - Experimental build for development and testing. - - ### Installation - ```bash - go get github.com/${{ github.repository }}/helix-client@${{ inputs.version }} - ``` - - ### Changes - Please see the commit history for detailed changes. - - ### Validation - - ✅ Tests passed - - ✅ Build successful - - ✅ Go vet clean - draft: false - prerelease: true \ No newline at end of file diff --git a/docs-src/blog/authors.yml b/docs-src/blog/authors.yml index 2af81d4d..376741b0 100644 --- a/docs-src/blog/authors.yml +++ b/docs-src/blog/authors.yml @@ -5,22 +5,22 @@ adarsha: image_url: https://github.com/a0d00kc.png aditya: name: Aditya Kumar - title: SDE-III @ Meesho + title: Lead Software Engineer @ Meesho url: https://github.com/Adit2607 image_url: https://github.com/Adit2607.png jigar: name: Jigar Dave - title: SDE-IV @ Meesho + title: Lead Software Engineer @ Meesho url: https://github.com/jigarpatel26 image_url: https://github.com/jigarpatel26.png jaya: name: Jaya Kumar - title: MLE-III @ Meesho + title: Lead ML Engineer @ Meesho url: https://github.com/jayakommuru image_url: https://github.com/jayakommuru.png bhawani: name: Bhawani Singh - title: SDE-IV @ Meesho + title: Architect @ Meesho url: https://github.com/singh-bhawani image_url: https://github.com/singh-bhawani.png mohit: diff --git a/docs-src/blog/bharatmlstack-history/post-five/bms.png b/docs-src/blog/bharatmlstack-history/post-five/bms.png new file mode 100644 index 00000000..b397fc88 Binary files /dev/null and b/docs-src/blog/bharatmlstack-history/post-five/bms.png differ diff --git a/docs-src/blog/bharatmlstack-history/post-five/index.md b/docs-src/blog/bharatmlstack-history/post-five/index.md new file mode 100644 index 00000000..6f488eec --- /dev/null +++ b/docs-src/blog/bharatmlstack-history/post-five/index.md @@ -0,0 +1,121 @@ +--- +slug: post-five +title: "LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale" +authors: [jaya] +date: 2025-6-2 +tags: [llm, vllm, tensorrt-llm, mlplatform, meesho, bharatmlstack] +--- + +![BharatMLStack](./bms.png) +## LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale + +Raw execution of Large Language Models is inherently expensive and memory-intensive. To achieve sub-second latency and high throughput, we implement a multi-layered optimization strategy that targets the entire inference stack—from memory management to kernel execution. + +## 1. Advanced Memory Management: Paged & Prefix KV Caching + +The most significant bottleneck in LLM inference is not always compute, but memory bandwidth—specifically managing the Key-Value (KV) cache. + +### Paged KV caching + +Standard caching suffers from fragmentation. We use **Paged KV caching**, which operates similarly to an operating system's virtual memory: the KV cache is divided into non-contiguous blocks. This lets us serve larger batch sizes without running out of memory. + +### KV cache quantization + +To further maximize available memory, we implement **KV cache quantization** (e.g., FP8). By compressing stored attention keys and values from 16-bit to 8-bit, we nearly double the effective context window capacity of the GPU, allowing longer conversations or larger batches without materially degrading quality. + +### Prefix caching (the "voice bot" optimizer) + +For use cases like GenAI voice bots where the system prompt (e.g., "You are a helpful assistant...") is static across thousands of requests, we enable **prefix caching**. + +- **Impact**: By reusing pre-computed KV states for common prefixes, we achieve a cache hit rate of ~90%. This reduces **Time To First Token (TTFT)** by skipping redundant computation of the system prompt. + +## 2. Aggressive Quantization (INT4 AWQ & FP8) + +Running models in their native 16-bit precision (BF16) restricts maximum batch size and throughput. We use quantization to shrink model weights without sacrificing accuracy. + +### INT4 AWQ (Activation-aware Weight Quantization) + +For the Llama 3 family, we use **AWQ** to compress weights to 4 bits. This reduces model size by ~75%, allowing larger models to fit into L4 GPU memory and significantly improving token generation speed. + +### FP8 precision + +For NVIDIA Hopper (H100) architectures, we are exploring **FP8 quantization**, leveraging native FP8 tensor cores to accelerate matrix multiplications while maintaining a higher dynamic range than integer quantization. + +- **Verification**: We validate quantized models by comparing dot-product similarity of embeddings against the FP16 baseline, consistently achieving **>99% similarity**. + +## 3. Kernel Fusion & Custom Plugins + +To minimize overhead from launching thousands of small GPU operations, we fuse them into monolithic kernels using NVIDIA TensorRT plugins. + +- **Flash attention & FMHA**: We enable **Fused Multi-Head Attention (FMHA)** combined with flash attention to reduce memory reads/writes. +- **GEMM plugins**: We use specialized **GEMM** plugins to accelerate transformer linear layers. +- **Removing input padding**: Instead of padding short sequences to match the longest, we remove input padding so the GPU processes only valid tokens. + +## 4. Inflight (Continuous) Batching + +Traditional static batching waits for all requests in a batch to finish before returning results—so one long response delays everyone else. + +We implement **inflight batching**: as soon as one request completes, its slot is freed and filled by a new request from the queue. This keeps GPUs saturated and decouples latency of short queries from long ones. + +## 5. Parallelism Strategies: Scaling Beyond One GPU + +For large models (e.g., 70B+ parameters) that cannot fit into the VRAM of a single GPU, we use parallelism strategies. + +- **Tensor parallelism (TP)**: Split weight matrices across multiple GPUs (e.g., 4× L4 or 8× A100). Each GPU computes a shard and outputs are reduced at every layer. +- **Pipeline parallelism (PP)**: Split model layers across GPUs to pipeline compute (e.g., while one GPU computes later layers for Request A, another starts early layers for Request B). + +## 6. Speculative Decoding + +To reduce inter-token latency (ITL), we explore **speculative decoding**. + +- **Mechanism**: A smaller, faster "draft" model speculatively generates a short token sequence (e.g., 5 tokens). +- **Verification**: The larger target model verifies those tokens in one parallel forward pass. If correct, we effectively generate multiple tokens per large-model step; if not, we discard and regenerate. This is effective for predictable text, improving perceived generation speed. + +## Few Benchmarks + +Below are a couple of representative use cases and performance numbers. + +### Search query rewriting + +- **LLM**: Fine-tuned llama-3.2-1B +- **Input & output token length**: ~10–20 +- **Response type**: Non-streaming + +| Inference runtime | Hardware | Max requests/sec | Max p99 latency | +| --- | --- | ---: | ---: | +| TensorRT-LLM | 4 × L4 GPUs (multi-GPU) | 1000 | 95 ms | +| TensorRT-LLM | 1 × A100 40 GB GPU | 1000 | 69 ms | + +### Voice bot query + +- **LLM**: Llama-3.1-8B +- **Input token length**: ~1900–2000 +- **Output token length**: ~200 +- **Response type**: Streaming + +| Inference runtime | Concurrency | p99 TTFT (ms) | p99 ITL (ms) | Token throughput (tokens/sec) | Request throughput (req/sec) | Hardware | +| --- | ---: | ---: | ---: | ---: | ---: | --- | +| TensorRT-LLM | 1 | 36.27 | 22.78 | 45.66 | 0.23 | L4 | +| TensorRT-LLM | 2 | 49.81 | 23.21 | 89.37 | 0.45 | L4 | +| TensorRT-LLM | 4 | 55.33 | 36.62 | 153.39 | 0.78 | L4 | +| TensorRT-LLM | 8 | 66.5 | 39.11 | 279.88 | 1.47 | L4 | +| TensorRT-LLM | 16 | 131.8 | 30.39 | 547.8 | 2.77 | L4 | +| TensorRT-LLM | 32 | 277.22 | 48.02 | 925.7 | 4.78 | L4 | +| TensorRT-LLM | 64 | 498.52 | 71.62 | 1,164.40 | 6.2 | L4 | +| TensorRT-LLM | 128 | 677.31 | 120.37 | 1,445.18 | 7.69 | L4 | +| TensorRT-LLM | 256 | 1,926.31 | 216.88 | 1,600.81 | 8.52 | L4 | +| TensorRT-LLM | 1 | 21.17 | 9.24 | 130.05 | 0.68 | A100 | +| TensorRT-LLM | 2 | 25.78 | 9.21 | 264.5 | 1.35 | A100 | +| TensorRT-LLM | 4 | 28.52 | 10.99 | 437.69 | 2.27 | A100 | +| TensorRT-LLM | 8 | 34.4 | 12.61 | 760.49 | 3.96 | A100 | +| TensorRT-LLM | 16 | 68.03 | 14.32 | 1,343.80 | 7.01 | A100 | +| TensorRT-LLM | 32 | 185.96 | 16.82 | 2,287.30 | 11.92 | A100 | +| TensorRT-LLM | 64 | 136.87 | 21.17 | 3,625.22 | 18.89 | A100 | +| TensorRT-LLM | 128 | 463.78 | 34.15 | 4,456.51 | 23.24 | A100 | +| TensorRT-LLM | 256 | 890.12 | 59.18 | 5,188.24 | 27.05 | A100 | + +## Conclusion + +High-performance LLM inference is fundamentally a systems engineering problem: memory efficiency, kernel execution, batching strategy, and parallelism determine real-world latency and throughput. Techniques such as paged KV caching, aggressive quantization, kernel fusion, and inflight batching improve GPU utilization while reducing latency and memory pressure. + +These optimizations enable the platform to deliver sub-second responses, sustain high concurrency, and efficiently serve both lightweight and long-context workloads. By continuously optimizing across the full inference stack, we keep LLM serving scalable, cost-efficient, and production-ready for real-time AI applications. diff --git a/docs-src/blog/bharatmlstack-history/post-four/bms.png b/docs-src/blog/bharatmlstack-history/post-four/bms.png new file mode 100644 index 00000000..b397fc88 Binary files /dev/null and b/docs-src/blog/bharatmlstack-history/post-four/bms.png differ diff --git a/docs-src/blog/bharatmlstack-history/post-four/index.md b/docs-src/blog/bharatmlstack-history/post-four/index.md new file mode 100644 index 00000000..23d97525 --- /dev/null +++ b/docs-src/blog/bharatmlstack-history/post-four/index.md @@ -0,0 +1,204 @@ +--- +slug: post-four +title: "Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving" +authors: [jaya] +date: 2025-3-29 +tags: [llm, vllm, tensorrt-llm, mlplatform, meesho, bharatmlstack] +--- + +![BharatMLStack](./bms.png) +## Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving + + + +Serving large language models in production introduces new challenges across infrastructure, performance optimization, and operational lifecycle management. The LLM Inference Platform addresses these challenges by providing a unified system for deploying and managing open-source and fine-tuned LLMs at scale. + +The platform implements a complete LLMOps lifecycle — from model registration and automated compilation to deployment, runtime optimization, and monitoring. Designed as a self-service environment, users can onboard models directly from open repositories such as Hugging Face or upload custom fine-tuned models, and deploy them using a single-click workflow with no manual infrastructure or configuration steps required. + +In addition to fully automated deployment, the platform allows users to select and apply custom inference optimization techniques — such as quantization strategies, batching configurations, and runtime-specific performance enhancements — enabling teams to balance latency, throughput, and cost based on their use case. The goal is to reduce operational friction while enabling high-performance, production-grade LLM inference. + +## Why LLM Inference Is not just bigger ML model serving + +Large language model (LLM) inference introduces a fundamentally different set of challenges compared to traditional machine learning inference. While classical ML models typically perform a single forward pass to produce a fixed prediction, LLMs operate as autoregressive systems, generating outputs token by token based on previously generated context. This difference dramatically changes how inference systems must be designed, optimized, and scaled. + +### Autoregressive Generation and Sequential Computation: + +Unlike traditional models such as classifiers or recommenders — where inference cost is relatively constant — LLMs generate responses incrementally. Each new token depends on all previously generated tokens, making inference inherently sequential and dynamic. This means latency and compute requirements vary significantly depending on prompt length and output size, introducing complexity in scheduling and resource allocation. +Because tokens cannot be generated fully in parallel during decoding, GPUs may become underutilized without specialized batching and scheduling strategies. This has led to the development of dedicated LLM inference engines optimized for token-level execution. + +### Prefill and Decode Phases: + +LLM inference typically consists of two distinct stages: + +- Prefill phase — the model processes the input prompt and builds internal representations. This stage is compute-heavy and highly parallelizable. +- Decode phase — the model generates tokens sequentially, predicting one token at a time using previously generated context. + +The decode stage often becomes memory-bound rather than compute-bound, which creates new performance bottlenecks compared to traditional ML workloads. + +### Context Management and KV Caching: + +Another fundamental difference lies in how LLMs maintain context. Transformer-based models rely on attention mechanisms that require access to past token representations. To avoid recomputing these representations repeatedly, inference engines use key-value (KV) caching, which stores intermediate activations from previous tokens. +KV caching significantly improves performance by eliminating redundant computation, but it introduces new challenges: + +- Memory consumption grows with sequence length and batch size +- GPU memory becomes a critical bottleneck +- Efficient memory management becomes essential for scaling concurrent requests + +This tradeoff between compute efficiency and memory usage is unique to LLM inference workloads. + +### Dynamic and Irregular Workloads: + +Traditional ML inference typically operates on fixed-size inputs with predictable latency. In contrast, LLM requests vary widely in prompt length, output length, and runtime behavior. As a result: + +- Batch sizes must be dynamic rather than static +- Requests may enter and leave batches asynchronously +- Scheduling systems must continuously rebalance workloads to maximize GPU utilization + +These characteristics require specialized serving architectures that differ significantly from standard ML serving pipelines. + +### Streaming and User Experience Constraints: + +Another distinguishing factor is the expectation of real-time streaming responses. Instead of returning a single output, LLM systems often stream tokens to users as they are generated. +Because of these differences — sequential generation, growing memory requirements, dynamic workloads, and streaming constraints — LLM inference cannot be treated as a simple extension of existing ML serving systems. Production platforms must incorporate specialized runtime engines, advanced optimization techniques, and observability tailored specifically to LLM workloads. + +## LLMOps: High-Level Architecture + +![LLM Architecture](./llm-plat.png) + +The LLM Inference Framework is designed as a fully automated, end-to-end system for deploying and operating open-source and fine-tuned large language models at scale. The architecture abstracts the complexity of model optimization, hardware selection, deployment, and runtime management into a unified workflow that enables users to move from raw model weights to production-ready inference endpoints with minimal manual intervention. + +Our LLM Inference Framework is architected not just as a serving engine, but as a complete lifecycle management system. As illustrated in the high-level design below, the platform automates the journey of a model through seven distinct stages, ensuring reproducibility, performance, and scalability. + +1. Onboarding & Registration (The Source of Truth) + + The lifecycle begins with the Data Scientist or engineer. + + - Model Ingestion: Users onboard models—whether open-source (Hugging Face, NeMo) or internally fine-tuned—via the Truffle Box SDK/UI. + - LLM + Prompt Registry: Unlike traditional systems that only track model weights, our registry is a unified control plane. It stores both the Model Artifacts and the Prompt Templates. This allows Data Scientists to register and version-control prompts (e.g., "customer_support_v2") independently of the application code. + +2. The "Black Box" Build Engine + + Once a model is registered, the Automated LLM Compiler + Quantizer Module kicks off a background job on ephemeral GPU resources. + + - Transformation: The raw model is converted into a TRT-LLM Checkpoint. + - Quantization: The system automatically applies quantization algorithms (like INT4 AWQ or FP8) to reduce memory footprint. + - Engine Building: Finally, it compiles a highly optimized TRT Engine specifically tuned for the target hardware. + +3. Intelligent Profiling & Validation + + Before deployment, the new engine passes through the Hardware & Inference Runtime Profiler. + + - Benchmarking: This module empirically tests the engine against various hardware configurations (L4 vs. A100) and runtimes (TRT-LLM vs. vLLM). + - Optimization: It recommends the optimal configuration that meets latency SLAs (Time-To-First-Token) while minimizing cost. + +4. Smart Artifact Generation & Distribution + + To solve the Kubernetes "Cold Start" problem, the LLM Serving Artifacts Generation module packages the model using a bifurcated strategy: + + - Standard Models: Artifacts are uploaded to Cloud Storage (GCS) and downloaded by pods at startup. + - Very Large Models: For massive models (>8GB) where network downloads are too slow, the system pre-caches the model onto Secondary Boot Disks. These disks are attached directly to new GPU nodes during autoscaling, eliminating download wait times. + +5. Image Streaming & Deployment + + Simultaneously, the inference runtime container images are pulled from the Artifact Registry. + + - Image Streaming: We utilize container image streaming to allow pods to start initializing while the massive Triton/Dynamo container layers are still downloading, further shaving seconds off the startup time. link + +6. The Inference Runtime (Kubernetes) + + The workload lands on Kubernetes with Autoscaling. + + - Dynamic Backends: Depending on the profile generated in Stage 3, the pod initializes either TensorRT-LLM (for throughput) or vLLM (for flexibility), or spins up a Dynamo worker for distributed inference. + - Data Loading: The pod either downloads the model from Cloud Storage or mounts the pre-warmed Secondary Boot Disk ("Pull from Disk"). + +7. Client Interaction & Observability + + Finally, the LLM Inference Client executes the request. + + - Prompt Injection: The client pulls the specific prompt template ID from the Registry, ensuring the exact versioned instructions are used. + - Streaming Response: The request is sent via gRPC, and tokens are streamed back to the user in real-time. + +8. Observability: Monitoring the Pulse of GenAI + + In traditional microservices, success is measured by CPU utilization and request latency (p99). For Large Language Models, these metrics are insufficient. A user doesn't care if the GPU is at 80% utilization; they care about how fast the first word appears and how smoothly the rest of the sentence follows. + + To capture the true user experience, our platform instrumentation focuses on three critical LLM-specific metrics: + + 1. Time to First Token (TTFT) + - Definition: TTFT measures the time elapsed from the moment a request is received until the very first token is generated and streamed back to the user. + - Why it matters: This represents the "Prefill Phase" latency—the time the model takes to process the input prompt and load weights. A high TTFT makes the application feel unresponsive or "hung." + - Optimization: We closely monitor TTFT to ensure our Prefix Caching is effective (aiming for high cache hitrates), which drastically lowers this metric by skipping redundant prompt processing. + + 2. Inter-Token Latency (ITL) + - Definition: ITL measures the average time interval between the generation of consecutive tokens during the "Decode Phase". + - Why it matters: This defines the "perceived speed" of reading. Even if the first token is fast (low TTFT), high ITL makes the text generation look "jerky" or slow to the user. + - Benchmarks: In our testing with Llama 3.1, we track p99 ITL to ensure it stays below human reading speeds to maintain a natural conversational flow. + + 3. Token Throughput vs. Request Throughput + - We distinguish between two types of throughput to balance system efficiency with user load: + - Token Throughput (tokens/sec): The total number of tokens generated across all concurrent requests. This measures the raw compute efficiency of the GPU and the effectiveness of batching. + - Request Throughput (req/sec): The number of distinct user queries served per second. We use this to determine autoscaling thresholds, ensuring we scale out before the queue depth impacts ITL. + + 4. The Monitoring Stack + - Real-time Dashboards: We utilize Grafana to visualize these streaming metrics in real-time, allowing on-call engineers to spot "slow generation" incidents that generic "500 error" alerts would miss. + - Request Tracing: Since Triton Inference Server does not log request payloads by default, we integrate a Helix Client to asynchronously publish request logs to Log Tables. This allows us to trace a specific "slow" request back to its prompt to understand if a complex input caused the latency spike. + +## Supported Inference backends (TensorRT LLM, Dynamo & vLLM) + +Tailored for the Use Case: We do not believe in a "one-size-fits-all" approach to inference. Different use cases—whether a real-time voice bot requiring ultra-lowsub-second latency or a massive reasoning task requiring huge context windows—demand different runtime characteristics. Our platform is designed to be runtime-agnostic, allowing us to automatically select and tailor the best engine based on the specific requirements of the application: + +1. TensorRT-LLM: The High-Performance Standard + + Suitable for: High-throughput production workloads where latency is critical (e.g., customer support chat, real-time voice bots). + + TensorRT-LLM serves as our default backend for these scenarios. Our internal benchmarks on Llama 3.1 and 3.2 models demonstrated that a tuned TensorRT-LLM engine significantly outperforms standard runtimes, especially when utilizing INT4 AWQ and FP8 quantization . + + Key optimizations we tailor for these high-load cases include: + + - Optimized execution via TensorRT engine compilation + - Quantization-aware execution for reduced memory usage and improved throughput + - Inflight Batching: Allowing requests to be processed continuously without waiting for the entire batch to finish, drastically improving GPU utilization . + - Custom Plugins: Enabling specific NVIDIA plugins like the GEMM plugin and GPT Attention plugin to accelerate matrix multiplications and attention mechanisms . + +2. Dynamo: Distributed Inference for Reasoning Models + + Suitable for: Very large "reasoning" models (70B+) or scenarios requiring massive context windows where a single GPU's memory is insufficient. + + For these memory-bound tasks, we utilize Dynamo, a low-latency distributed inference framework . Unlike monolithic servers, Dynamo disaggregates the inference process to scale resources horizontally: + + - KV Aware Routing: A specialized router directs requests to workers that already hold the relevant Key-Value (KV) cache, minimizing redundant computation . + - Prefill vs. Decode Split: The workload is divided into Prefill Workers (processing the prompt) and Decode Workers (generating tokens), allowing us to scale the compute-heavy "reading" phase independently from the memory-heavy "writing" phase . + - Distributed execution across multiple GPU resources + +3. vLLM: The Flexible Baseline + + Suitable for: Rapid prototyping, testing new model architectures, or low-traffic internal tools where ease of deployment outweighs raw throughput. + + While TensorRT-LLM is optimized for maximum speed, vLLM provides a robust and flexible baseline . + + - High throughput through dynamic batching and efficient memory utilization + - Paged KV cache management for handling long contexts and concurrent requests + - Strong support for open-source model ecosystems + - Rapid Adoption: It allows us to onboard new model architectures immediately without waiting for a custom TensorRT build. + - Benchmarking Insight: In our internal tests, vLLM provided a strong baseline but often lacked the specific max-token optimizations present in our custom TRT engines . We use it strategically for initial testing before committing to a full TensorRT optimization pipeline. + +## Conclusion + +Large language model inference introduces a fundamentally new class of infrastructure challenges—where performance is governed not just by raw compute, but by memory efficiency, intelligent scheduling, runtime specialization, and lifecycle automation. Unlike traditional ML serving, LLM inference requires systems that understand token-level execution, manage rapidly growing context state, and continuously balance latency, throughput, and cost under highly dynamic workloads. + +The LLM Inference Framework addresses these challenges by transforming inference into a fully automated, reproducible lifecycle—from model onboarding and compilation to deployment, optimization, and observability. By integrating automated quantization and engine compilation, intelligent runtime selection, cold-start mitigation strategies, and LLM-specific observability metrics such as Time-to-First-Token and Inter-Token Latency, the platform ensures both high performance and operational simplicity. + +Equally important, the framework is designed with flexibility and future evolution in mind. Its runtime-agnostic architecture enables seamless adoption of emerging inference engines, hardware accelerators, and optimization techniques without requiring platform redesign. This ensures that teams can continuously leverage advancements in the rapidly evolving LLM ecosystem while maintaining consistent operational workflows. + +Ultimately, the goal of the platform is to make production-scale LLM deployment as seamless and reliable as traditional software deployment—allowing teams to focus on building intelligent applications rather than managing infrastructure complexity. By combining lifecycle automation, runtime optimization, and deep observability, the LLM Inference Framework provides a scalable foundation for delivering fast, cost-efficient, and production-ready LLM experiences. + +## Future Explorations + +While we have achieved significant milestones in latency and throughput, the landscape of GenAI is evolving rapidly. Our roadmap focuses on increasing flexibility, reducing costs, and enhancing reliability for enterprise-grade workloads. Here is what we are building next: + +- TPU Support: To diversify our hardware supply chain and further optimize cost-per-token, we are evaluating Google Cloud TPUs to bake it into our platform. By leveraging the JAX and PyTorch/XLA ecosystems, we aim to unlock the massive throughput potential of TPU v5e chips, particularly for our open-source Llama models. This will allow the hardware profiler to dynamically choose between NVIDIA GPUs and Google TPUs based on real-time availability and price-performance metrics. +- Multi-LoRA Serving (Serverless Experience): Currently, deploying a fine-tuned model requires a dedicated GPU. We are building support for Multi-LoRA serving, which will allow us to serve hundreds of unique, fine-tuned adapters on top of a single frozen base model. This will drastically reduce costs for multi-tenant applications, enabling a "serverless" experience where specific fine-tunes are hot-swapped instantly per request. +- Spot Instance Orchestration: To further optimize cloud costs, we are developing fault-tolerant mechanisms to run inference workloads on Spot Instances. By implementing aggressive checkpointing and seamless request draining, we aim to leverage cheaper, preemptible compute capacity without interrupting the user's streaming experience. +- Semantic Caching Layer: We plan to move beyond standard Prefix Caching to implement Semantic Caching. By using a vector database to fetch responses for semantically similar queries (e.g., "How do I reset my password?" vs. "Password reset steps"), we can bypass the GPU entirely for repetitive queries, reducing latency to near-zero. +- Context-Aware Autoscaling: Standard CPU/GPU utilization metrics are often insufficient signals for scaling LLMs. We are working on KV-cache pressure metrics for autoscaling. This ensures that we scale out before the memory fills up, preventing eviction-based slowdowns during traffic spikes. +- Online Evaluation & Guardrails: We are integrating a lightweight "Trust Layer" into the proxy. This will allow for low-latency input/output filtering (Guardrails) and asynchronous "LLM-as-a-Judge" evaluation pipelines to monitor response quality in production, not just system health. \ No newline at end of file diff --git a/docs-src/blog/bharatmlstack-history/post-four/llm-plat.png b/docs-src/blog/bharatmlstack-history/post-four/llm-plat.png new file mode 100644 index 00000000..1f0fa9f7 Binary files /dev/null and b/docs-src/blog/bharatmlstack-history/post-four/llm-plat.png differ diff --git a/docs-src/blog/bharatmlstack-history/post-one/bms.png b/docs-src/blog/bharatmlstack-history/post-one/bms.png new file mode 100644 index 00000000..b397fc88 Binary files /dev/null and b/docs-src/blog/bharatmlstack-history/post-one/bms.png differ diff --git a/docs-src/blog/bharatmlstack-history/post-one/index.md b/docs-src/blog/bharatmlstack-history/post-one/index.md index aa933741..cb74fd35 100644 --- a/docs-src/blog/bharatmlstack-history/post-one/index.md +++ b/docs-src/blog/bharatmlstack-history/post-one/index.md @@ -6,7 +6,7 @@ date: 2022-11-15 tags: [online-feature-store, interaction-store, mlplatform, meesho] --- -![BharatMLStack](./bharatmlstack.png) +![BharatMLStack](./bms.png) ## The Genesis: How a Friday Night Roast Sparked Meesho’s ML Platform It all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting—until one remark hit a little too close to home: diff --git a/docs-src/blog/bharatmlstack-history/post-three/bms.png b/docs-src/blog/bharatmlstack-history/post-three/bms.png new file mode 100644 index 00000000..b397fc88 Binary files /dev/null and b/docs-src/blog/bharatmlstack-history/post-three/bms.png differ diff --git a/docs-src/blog/bharatmlstack-history/post-three/index.md b/docs-src/blog/bharatmlstack-history/post-three/index.md new file mode 100644 index 00000000..96598905 --- /dev/null +++ b/docs-src/blog/bharatmlstack-history/post-three/index.md @@ -0,0 +1,104 @@ +--- +slug: post-three +title: "Cracking the Code: Scaling Model Inference & Real-Time Embedding Search" +authors: [aditya, jaya, adarsha] +date: 2024-05-21 +tags: [model-inference, embedding-search, mlplatform, meesho, bharatmlstack] +--- + +![BharatMLStack](./bms.png) + +## Cracking the Code: Scaling Model Inference & Real-Time Embedding Search + +By mid-2023, we had transformed our ML stack—building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained: + +- 🔹 Scaling model inference without hitting infrastructure roadblocks +- 🔹 Moving embedding search from batch to real-time for candidate generation + +Here’s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system. + +## Breaking Free from the Scalability Ceiling + +### The Model Serving Bottleneck—A Wake-Up Call + +July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue—scaling our model-serving infrastructure was taking 10–15 minutes. In real-time ML, that’s an eternity. +In one of our war rooms, we ran a quick experiment: + +- 🚀 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine. +- 🚀 Fired requests and compared the outputs with our existing cloud-hosted setup. +- 🚀 The results matched—perfectly. + +That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn't allocate enough compute resources in time. Luckily, they did—but the seed was planted. +Then in October, just two weeks before MBS, we got an alarming response from our infrastructure team: + "Node availability may be an issue." +With no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results? + +- ✅ p99 latency dropped from 90–100ms to 30–40ms +- ✅ Triton handled significantly higher throughput on fewer resources +- ✅ No model changes were needed + +MBS ran without a hitch, proving that self-hosted inference was the way forward. + +### Scaling Triton on GKE + +This left us with two choices: + +- 1️⃣ Port models to a managed cloud inference service, investing time in learning a new deployment stack +- 2️⃣ Scale our existing Triton setup on GKE, optimizing for cost and performance + +We went with Option 2—and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations. + +### Fixing the Cold Start Problem + +As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7–9 minutes to spin up. + +After profiling, we found the culprits: + +- Triton’s base image—a massive 5GB +- Model binaries—often 1GB+ +- Startup delay—mostly due to downloading and initializing these assets + +To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother. + +## Embedding Search: The Last Piece of the Puzzle + +By mid-2023, most of our ML stack had gone real-time—except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system. + +### Choosing the Right Vector Database + +We benchmarked three production-ready vector DBs across key parameters: + +- Milvus +- Qdrant +- Weaviate + +After extensive POCs, Qdrant stood out for its: + +- ✅ Blazing-fast search latency on high-dimensional vectors +- ✅ Efficient memory usage, crucial for in-memory workloads +- ✅ Support for upserts and soft deletes, vital for Ads use cases +- ✅ gRPC + REST APIs, making integration seamless +- ✅ Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.) + +At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search—a perfect fit for our needs. + +### Embedding Freshness & Real-Time Updates + +To ensure embeddings stayed up to date, we built a dual ingestion pipeline: + +- 📌 Daily Refresh: A bulk pipeline updated embeddings overnight +- 📌 Real-Time Updates: Ads events triggered immediate upserts/deletes + +This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds. + +![Skye](./vss.png) + +## Final Takeaways: Scaling Smartly for Real-Time ML + +- 🚀 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services +- 🚀 Building a custom Triton image reduced cold starts, improving responsiveness +- 🚀 Qdrant-based embedding search enabled real-time personalization at scale +- 🚀 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations + +By early 2024, Meesho’s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead. + diff --git a/docs-src/blog/bharatmlstack-history/post-three/vss.png b/docs-src/blog/bharatmlstack-history/post-three/vss.png new file mode 100644 index 00000000..c6b18475 Binary files /dev/null and b/docs-src/blog/bharatmlstack-history/post-three/vss.png differ diff --git a/docs-src/blog/bharatmlstack-history/post-two/bms.png b/docs-src/blog/bharatmlstack-history/post-two/bms.png new file mode 100644 index 00000000..b397fc88 Binary files /dev/null and b/docs-src/blog/bharatmlstack-history/post-two/bms.png differ diff --git a/docs-src/blog/bharatmlstack-history/post-two/index.md b/docs-src/blog/bharatmlstack-history/post-two/index.md new file mode 100644 index 00000000..9c33346d --- /dev/null +++ b/docs-src/blog/bharatmlstack-history/post-two/index.md @@ -0,0 +1,150 @@ +--- +slug: post-two +title: "Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)" +authors: [bhawani, jigar, adarsha] +date: 2023-4-10 +tags: [inferflow, interaction-store, mlplatform, meesho, bharatmlstack] +--- + +![BharatMLStack](./bms.png) +## Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2) + +By late 2022, we had built something we were truly proud of—a real-time ML serving system with a DAG-based executor, a feature store, and an interaction store powering key ranking and personalization models. It was a major milestone, the culmination of months of effort from data scientists, ML engineers, and backend teams. Our system was live, and we were ready to push the boundaries of experimentation. +And it worked. Mostly. +But soon, cracks appeared. Every new model needed custom feature retrieval logic, DAGs became dense and unmanageable, and scaling turned into a constant firefight. Costs surged, and infra bottlenecks slowed experimentation. Our system worked, but it wasn’t built for scale. +This is the story of how we tackled these challenges—building Inferflow for seamless feature retrieval, optimizing real-time infra, and cutting costs while scaling to millions of QPS. + +### The Cost of Success +Every new Ranker model required its own feature set, often pulling from different entities. Each addition meant: + +- Adding new DAG nodes in IOP +- Writing custom logic to fetch features from multiple sources (e.g., user, product, user × category) +- Inferring intermediate features (e.g., extracting category from a product to fetch user × category data) +- Optimizing I/O and dealing with the inevitable bugs + +What began as clean DAGs soon turned into a tangled web of cross-dependent graphs. Every experimentation cycle meant new nodes, new dependencies, and slower iterations. + +### Scaling Pains (and Cassandra’s Limits) +At some point, we were hitting: + +- 250–300K reads/sec +- 1M writes/sec (during lean hours) + +All of this ran on Cassandra. While its distributed architecture had been proven in production, operating large-scale clusters came with considerable infrastructure overhead. Our proof-of-concept (POC) demonstrated throughput of around 100K ops/sec, but as we scaled further, the challenges grew. Ensuring node health, optimizing compaction, and maintaining storage balance became increasingly demanding. We also observed latency spikes under heavy load, alongside a sharp increase in total cost of ownership. + +### Interaction Store Woes +Our interaction store was another ticking time bomb: + +- 🚨 Clusters kept growing in size and cost +- 🚨 Latency spikes became increasingly frequent +- 🚨 The DMC proxy occasionally lost locality of nodes against shards, causing cross-node communication and degraded performance + +Each time this happened, we had to manually rebalance shards just to restore stable latency, making operations unsustainable at scale. + +### Silver Linings +Despite the chaos, the system was live and delivering value: + +- Real-time infrastructure was in production +- Costs dropped by 60–70% compared to offline personalization +- New experiments rolled out faster and more successfully +- User engagement metrics improved + +It wasn’t perfect. It was far from easy. But it worked—and that counted for a lot. + +### Round Two: Solving the Top 2 Bottlenecks +With the first-gen system stretched to its limits, we stepped back. Conversations with data scientists and backend engineers revealed three recurring pain points: + +1. Coding feature retrieval logic for every new model was becoming unsustainable +2. ML scale was exploding—bringing rising infra costs with it +3. Real-time embedding search was the next big unlock + +We tackled them one by one—starting with the biggest pain point. + +#### Problem 1: No-Code Feature Retrieval for Model Inference +We noticed a pattern: for personalized ranking, models needed features from: + +- ✅ Product +- ✅ User +- ✅ User × Category +- ✅ Region, cohort, sub-category, etc. + +A key insight emerged: Entities that contribute features for a model always map back to the context entities. + +![MP Dag](./mp-dag.png) + +With this, we designed Inferflow, a graph-driven feature retrieval and model orchestration system: + +- 1️⃣ Inferflow takes a modelId and context IDs (e.g., userId, productIds) +- 2️⃣ Loads a pre-defined feature retrieval graph from ZooKeeper +- 3️⃣ Executes the graph to resolve entity relationships dynamically +- 4️⃣ Outputs a 2D matrix of feature vectors + +💡 The impact? + +- 🚀 No more custom feature retrieval code—just graph updates in config +- 🚀 Feature consistency across experiments +- 🚀 Faster iteration cycles for ranking, fraud detection, and beyond + +Here’s a visual example that shows how this graph plays out during execution. We further extended the graph to call multiple models as needed: +![MP matrix](./mp-matrix.png) +We built Inferflow in GoLang, using gRPC and Proto3 serialization for efficiency. + +#### Problem 2: Scaling Without Breaking the Bank +With more ML use cases coming online, we needed to cut costs without compromising performance. We focused on: + +- 🔹 Online Feature Store +- 🔹 Interaction Store + +#### Optimizing the Online Feature Store +Our costs were concentrated in: + +- 📌 Database (Cassandra) +- 📌 Cache (Redis) +- 📌 Running Pods (Java services) + +1️⃣ Replacing Cassandra with ScyllaDB +As we hit the operational limits of large Cassandra clusters, we transitioned to ScyllaDB, which offered a seamless drop-in replacement without major code changes. The switch brought significant benefits: + +- Throughput: Matched or exceeded Cassandra's performance under identical workloads, even under high concurrency. +- Latency: Achieved consistently lower P99 latencies due to ScyllaDB's shard-per-core architecture and better I/O utilization. +- Cost Efficiency: Reduced infra footprint by ~70% through better CPU and memory efficiency, eliminating the need for over-provisioned nodes. + +2️⃣ Finding the Right Cache +To reduce backend load and improve response times, we benchmarked multiple caching solutions—Memcached, KeyDB, and Dragonfly—under real production traffic patterns. Dragonfly stood out due to its robust architecture and operational simplicity: + +- Data Skew Handling: Efficiently managed extreme key hotness and uneven access patterns without performance degradation. +- Throughput: Delivered consistently high throughput, even with large object sizes and concurrent access. +- Ease of Adoption: Acted as a drop-in Redis replacement with full protocol compatibility—no changes needed in application code or client libraries. + +3️⃣ Moving to GoLang for Cost-Efficient Serving +Java services were memory-heavy—so we rewrote core services in GoLang. The results? + +✅ Memory usage dropped by ~80% +✅ CPU utilization was significantly lower +✅ Faster, more efficient deployments + +#### Optimizing the Interaction Store +We realized that we only need a user’s interaction data in Redis when they open the app. So, we implemented a tiered storage approach: + +- 📌 Cold Tier (ScyllaDB)—Stores click, order, wishlist events +- 📌 Hot Tier (Redis)—Loads a user’s past interactions only when they open the app + +Smart Offloading: We introduced an inactivity tracker to detect when a user session ends. At that point, Redis data was flushed back to Scylla, reducing unnecessary writes. + +![InteractionStore](./interaction-str.png) +#### Results + +- Online Feature Store hit 1M QPS for the first time during the 2023 Mega Blockbuster Sale—without breaking a sweat +- Infra costs for Online Feature Store and Interaction Store dropped by ~60% + +#### The Catch: Our ML Hosting Hit a Hard Limit +While planning for 2023 MBS, we ran into a critical scalability bottleneck: + +- ❌ Insufficient compute availability in our region for ML instances +- ❌ Couldn’t provision enough nodes to handle real-time inference at scale + +This forced us to rethink where and how we hosted our models. The existing setup was great for prototyping—but it wasn’t built to handle the bursty, high-QPS demands of real-world production workloads. + +### Conclusion: From Firefighting to Future-Proofing +What started as an ambitious experiment turned into a real-time ML infrastructure that powered millions of requests per second. We battled scaling pains, rethought feature retrieval with Inferflow, and rebuilt our infra stack for efficiency—driving down costs while improving experimentation velocity. +But new challenges emerged. Our infrastructure could now handle scale, but our ML model hosting setup hit a hard limit. With compute availability bottlenecks threatening real-time inference, we faced a critical decision: how do we make model serving as scalable and cost-efficient as the rest of our stack? That’s the next piece of the puzzle—and the story of Part 3. diff --git a/docs-src/blog/bharatmlstack-history/post-two/interaction-str.png b/docs-src/blog/bharatmlstack-history/post-two/interaction-str.png new file mode 100644 index 00000000..99ddd4e9 Binary files /dev/null and b/docs-src/blog/bharatmlstack-history/post-two/interaction-str.png differ diff --git a/docs-src/blog/bharatmlstack-history/post-two/mp-dag.png b/docs-src/blog/bharatmlstack-history/post-two/mp-dag.png new file mode 100644 index 00000000..4a13af56 Binary files /dev/null and b/docs-src/blog/bharatmlstack-history/post-two/mp-dag.png differ diff --git a/docs-src/blog/bharatmlstack-history/post-two/mp-matrix.png b/docs-src/blog/bharatmlstack-history/post-two/mp-matrix.png new file mode 100644 index 00000000..44b21256 Binary files /dev/null and b/docs-src/blog/bharatmlstack-history/post-two/mp-matrix.png differ diff --git a/docs-src/docs/inferflow/_category_.json b/docs-src/docs/inferflow/_category_.json new file mode 100644 index 00000000..384c93bd --- /dev/null +++ b/docs-src/docs/inferflow/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Inferflow", + "position": 2, + "link": { + "type": "generated-index", + "description": "Inferflow is a graph-driven feature retrieval and model inference orchestration engine. It dynamically resolves entity relationships via configurable DAGs, retrieves features from the Online Feature Store, and orchestrates model scoring — all without custom code." + } +} diff --git a/docs-src/docs/inferflow/v1.0.0/_category_.json b/docs-src/docs/inferflow/v1.0.0/_category_.json new file mode 100644 index 00000000..0641455e --- /dev/null +++ b/docs-src/docs/inferflow/v1.0.0/_category_.json @@ -0,0 +1,9 @@ +{ + "label": "v1.0.0", + "position": 1, + "link": { + "type": "generated-index", + "description": "Inferflow v1.0.0", + "slug": "/inferflow/v1.0.0" + } +} diff --git a/docs-src/docs/inferflow/v1.0.0/architecture.md b/docs-src/docs/inferflow/v1.0.0/architecture.md new file mode 100644 index 00000000..789e9a4d --- /dev/null +++ b/docs-src/docs/inferflow/v1.0.0/architecture.md @@ -0,0 +1,267 @@ +--- +title: Architecture +sidebar_position: 1 +--- + +# BharatMLStack - Inferflow + +Inferflow is part of **BharatMLStack**, a graph-driven feature retrieval and model inference orchestration engine built in **Go**. It eliminates the need for custom feature retrieval code by using configurable DAG topologies to dynamically resolve entity relationships, fetch features from the Online Feature Store, and orchestrate model scoring — all driven by configuration stored in **etcd**. + +--- + +## Overview + +In a typical ML serving pipeline, every new model requires bespoke code to: +- Fetch features from multiple entities (user, product, user x category, etc.) +- Infer intermediate entity relationships (e.g., extract category from product to fetch user x category data) +- Orchestrate one or more model inference calls +- Handle I/O, batching, and error propagation + +Inferflow abstracts all of this behind a **config-driven DAG executor**. Given a `model_config_id` and context entities (e.g., `userId`, `productIds`), it: + +1. Loads a pre-defined feature retrieval and inference graph from etcd +2. Executes the graph to resolve entity relationships dynamically +3. Retrieves features from the Online Feature Store (OnFS) in parallel +4. Calls model serving endpoints (Predator) and compute services (Numerix) +5. Returns scored results as a structured response + +--- + +## High-Level Architecture + +![Inferflow Architecture - DAG Topology Executor](../../../static/img/v1.0.0-inferflow-arch.png) + +The diagram shows the internal DAG structure of Inferflow's topology executor. gRPC APIs (Pair, Point, Slate) feed into the DAG, where **Feature Init** bootstraps the ComponentMatrix. Feature components (FS User, FS Product, FS Region, FS User Cat, FS Region Scat) fetch features from **OnFS** in parallel and populate columns in the shared **2D Result Matrix**. Model components (Model A, Model B) call **Predator** for inference, and compute components call **Numerix** for operations like reranking. The entire DAG topology is driven by config loaded from **etcd**. + +--- + +## Core Components + +### 1. gRPC Server + +Inferflow exposes its APIs via a gRPC server, with HTTP health endpoints multiplexed on the same port using **cmux**. The server provides: + +- **Inferflow API** — `RetrieveModelScore`: entity-based feature retrieval and scoring +- **Predict API** — `InferPointWise`, `InferPairWise`, `InferSlateWise`: structured inference with targets, pairs, and slates + +### 2. DAG Topology Executor + +The heart of Inferflow. Each model configuration defines a `component_dependency` map that describes a Directed Acyclic Graph (DAG) of components. + +**Execution model:** +- Uses **Kahn's algorithm** for topological ordering +- Components at the same level run **concurrently** in goroutines +- All components share a mutable `ComponentMatrix` (rows = entity IDs, columns = features/scores) +- DAG topologies are **cached** using Murmur3 hashing with Ristretto cache + +**Validation:** +- Cycle detection via in-degree analysis +- Component existence verification against the `ComponentProvider` + +### 3. Component Types + +Inferflow defines four types of DAG components: + +| Component | Role | External Dependency | +|-----------|------|---------------------| +| **FeatureInitComponent** | Root node — initializes the `ComponentMatrix` with entity IDs and schema | None | +| **FeatureComponent** | Fetches features from the Online Feature Store for a specific entity type | OnFS (gRPC) | +| **PredatorComponent** | Calls model serving endpoints for inference scoring | Predator / Helix (gRPC) | +| **NumerixComponent** | Calls compute engine for operations like reranking | Numerix (gRPC) | + +### 4. ComponentMatrix — The 2D Result Matrix + +The ComponentMatrix is a shared, mutable 2D data structure that flows through the entire DAG. Every component reads from and writes to this matrix, progressively building a complete feature + score row for each entity. + +![DAG Execution & 2D Matrix Flow](../../../static/img/v1.0.0-inferflow-dag-matrix.png) + +#### How the matrix evolves through the DAG + +The diagram above illustrates the three execution phases and how the 2D matrix grows at each stage: + +**Phase 1 — Feature Retrieval** + +The **init** node creates an empty matrix with one row per target entity ID. Feature components then execute — first the top-level entities (entity A, entity B) fetch their features from OnFS and populate their columns (shown as colored blocks). Derived entities (entity C, D, E) resolve their keys from the already-populated columns and add more feature columns. At this point the matrix contains all feature data, with each color representing features from a different entity. + +The right side of the diagram shows the matrix being **decomposed** — feature columns from different entities are separated into per-model input groups, selecting only the features each model needs. + +**Phase 2 — Model Invocation** + +Model X and Model Y each receive their decomposed feature slices, call **Predator** for inference, and write score columns back into the matrix (shown as new colored columns appended to the right). Multiple models can run in parallel if they don't depend on each other's outputs. + +The scores are then decomposed again to prepare inputs for the compute stage. + +**Phase 3 — Numerix Compute** + +The **Score Comb** node takes score columns from both models, calls **Numerix** for a final compute operation (e.g., score combination, reranking), and writes the final score column (shown in dark red) into the matrix. The result is a complete row per entity with all features and all scores. + +#### Matrix structure + +| Property | Description | +|----------|-------------| +| **Rows** | One per target entity ID (e.g., each product being scored) | +| **String columns** | Human-readable values used in responses | +| **Byte columns** | Binary-encoded feature values used for model inputs | +| **Column naming** | `entity_label:feature_group:feature_name` | + +Each component only reads the columns it needs and writes to its own columns, enabling safe concurrent execution across independent branches of the DAG. + +For slate-based APIs, a companion `SlateData` structure holds per-slate matrices and scores, with `slate_target_indices` mapping slates to rows in the main matrix. + +### 5. Configuration Management (etcd) + +Model configurations are stored in etcd and hot-reloaded via watchers: + +- **Config paths**: `/config/inferflow/services/`, `/model-config` +- **Watch mechanism**: etcd watchers trigger `ReloadModelConfigMapAndRegisterComponents` on any change +- **On reload**: Updates `ConfigMap`, re-initializes feature schemas, and re-registers DAG components + +This means new models or configuration changes go live **without redeployment**. + +### 6. External Integrations + +#### Online Feature Store (OnFS) +- gRPC client calling `FeatureService.RetrieveFeatures` +- Batched retrieval with configurable batch size and deadline +- Auth via `CALLER_ID` and `CALLER_TOKEN` metadata + +#### Predator (Model Serving) +- Uses `go-sdk` for model inference +- Supports **percentage-based traffic routing** across multiple model endpoints +- Configurable calibration and batch sizing + +#### Numerix (Compute Engine) +- Uses `go-sdk` Numerix client +- RPC: `NumerixService.Compute` with entity score data +- Used for compute operations like reranking + +#### Kafka (Inference Logging) +- Async inference log publishing using `segmentio/kafka-go` +- Supports **Proto**, **Arrow**, and **Parquet** serialization formats +- Configurable sampling via `LoggingPerc` and user-based daily sampling + +--- + +## Request Flow + +``` +1. Client sends gRPC request with model_config_id + entity IDs + │ +2. Load ModelConfig from etcd-backed ConfigMap + │ +3. Adapt proto request → ComponentRequest + (build ComponentMatrix with entity schema) + │ +4. Resolve DAG topology from component_dependency config + │ +5. Execute DAG (Kahn's algorithm, concurrent): + │ + ├─ FeatureInitComponent: populate matrix with entity IDs + schema + │ + ├─ FeatureComponents (parallel): fetch features from OnFS → fill matrix columns + │ + ├─ PredatorComponent: build feature payloads from matrix → call model → write scores + │ + └─ NumerixComponent: read scores from matrix → call compute → write final scores + │ +6. Build response from matrix columns per ResponseConfig + │ +7. (Optional) Async Kafka logging of inference features and scores + │ +8. Return gRPC response to client +``` + +--- + +## Observability + +### Metrics (StatsD / Telegraf) + +| Metric | Description | +|--------|-------------| +| `inferflow.retrievemodelscore.request.total` | Total RetrieveModelScore requests | +| `inferflow.retrievemodelscore.latency` | End-to-end latency | +| `inferflow.retrievemodelscore.batch.size` | Batch size per request | +| `predict.infer.request.total` | Total Predict API requests | +| `predict.infer.latency` | Predict API latency | +| `inferflow.component.execution.total` | Per-component execution count | +| `inferflow.component.execution.latency` | Per-component latency | +| `inferflow.component.execution.error` | Component-level errors | +| `inferflow.component.feature.count` | Feature count per component | +| `inferflow.external.api.request.total` | External API call count | +| `inferflow.external.api.latency` | External API latency | +| `inferflow.component.inmemorycache.request.total` | Cache hit/miss total | +| `inferflow.component.inmemorycache.miss` | Cache misses | +| `inferflow.logging.kafka_sent` | Kafka log messages sent | + +### Logging +- Structured JSON logging via **zerolog** +- Configurable log levels + +--- + +## Deployment + +### Docker + +Inferflow ships as a multi-stage Docker image: + +- **Builder**: Go 1.19 Alpine with optional Kafka support (librdkafka) +- **Runtime**: Debian 10 slim +- **Build command**: `go build -tags musl -ldflags "-extldflags -static" -o server cmd/${module}/main.go` + +### Supported Environments +- Kubernetes (K8s) +- Google Kubernetes Engine (GKE) +- Amazon EKS + +### Configuration +All configuration is driven via environment variables (loaded by Viper) and etcd. No config files are required at deployment time. + +--- + +## Target Users + +| User | Role | +|------|------| +| Data Scientists | Define model configs and feature retrieval graphs via config — no code needed | +| ML Engineers | Onboard new models by updating etcd config; manage DAG topologies | +| Backend Developers | Integrate via gRPC SDKs for real-time scoring in application services | +| Platform Engineers | Deploy, scale, and monitor Inferflow clusters | + +--- + +## Benefits + +- **No-code feature retrieval** — new models need only a config change, not custom code +- **Feature consistency** — same graph-driven retrieval ensures identical features across experiments +- **Faster iteration** — experiment with new models in minutes, not days +- **Concurrent execution** — DAG components run in parallel for minimal latency +- **Hot reloading** — model config changes via etcd go live without redeployment +- **Multi-API support** — PointWise, PairWise, and SlateWise inference patterns out of the box +- **Production-grade** — built in Go with gRPC, designed for millions of QPS + +--- + +## Contributing + +We welcome contributions from the community! Please see our [Contributing Guide](https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md) for details on how to get started. + +## Community & Support + +- **Discord**: Join our [community chat](https://discord.gg/XkT7XsV2AU) +- **Issues**: Report bugs and request features on [GitHub Issues](https://github.com/Meesho/BharatMLStack/issues) +- **Email**: Contact us at [ml-oss@meesho.com](mailto:ml-oss@meesho.com) + +## License + +BharatMLStack is open-source software licensed under the [BharatMLStack Business Source License 1.1](https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md). + +--- + +
+ Built with ❤️ for the ML community from Meesho +
+
+ If you find this useful, ⭐️ the repo — your support means the world to us! +
diff --git a/docs-src/docs/inferflow/v1.0.0/configuration.md b/docs-src/docs/inferflow/v1.0.0/configuration.md new file mode 100644 index 00000000..35b9b1bd --- /dev/null +++ b/docs-src/docs/inferflow/v1.0.0/configuration.md @@ -0,0 +1,366 @@ +--- +title: Configuration Guide +sidebar_position: 3 +--- + +# Inferflow - Configuration Guide + +Inferflow is fully config-driven. All model onboarding, feature retrieval logic, DAG topology, and inference behavior are controlled through configuration stored in **etcd** — with zero code changes required. + +--- + +## Configuration Overview + +Inferflow configuration is organized into two layers: + +1. **Static config** — Environment variables loaded at startup (via Viper) +2. **Dynamic config** — Model configurations stored in etcd, hot-reloaded on change + +--- + +## Static Configuration (Environment Variables) + +These are set at deployment time and require a restart to change. + +### Server + +| Variable | Description | Example | +|----------|-------------|---------| +| `APP_PORT` | gRPC/HTTP server port | `50051` | +| `APP_ENV` | Environment name | `production` | + +### etcd + +| Variable | Description | Example | +|----------|-------------|---------| +| `ETCD_ENDPOINTS` | Comma-separated etcd endpoints | `etcd-0:2379,etcd-1:2379` | +| `ETCD_DIAL_TIMEOUT` | Connection timeout | `5s` | + +### Online Feature Store (OnFS) + +| Variable | Description | Example | +|----------|-------------|---------| +| `externalServiceOnFs_host` | OnFS gRPC host | `onfs-api:50051` | +| `externalServiceOnFs_callerId` | Caller ID for auth | `inferflow` | +| `externalServiceOnFs_callerToken` | Caller token for auth | `` | +| `externalServiceOnFs_batchSize` | Batch size for feature retrieval | `100` | +| `externalServiceOnFs_deadline` | Request deadline | `200ms` | + +### Predator (Model Serving) + +| Variable | Description | Example | +|----------|-------------|---------| +| `externalServicePredator_defaultDeadline` | Default inference deadline | `100ms` | + +### Numerix (Compute Engine) + +| Variable | Description | Example | +|----------|-------------|---------| +| `numerixClientV1_host` | Numerix gRPC host | `numerix:50052` | +| `numerixClientV1_deadline` | Request deadline | `100ms` | + +### Kafka (Inference Logging) + +| Variable | Description | Example | +|----------|-------------|---------| +| `KafkaBootstrapServers` | Kafka broker addresses | `kafka-0:9092,kafka-1:9092` | +| `KafkaLoggingTopic` | Topic for inference logs | `inferflow-logs` | + +### Metrics (StatsD / Telegraf) + +| Variable | Description | Example | +|----------|-------------|---------| +| `TELEGRAF_HOST` | StatsD host | `telegraf` | +| `TELEGRAF_PORT` | StatsD port | `8125` | + +### In-Memory Cache + +| Variable | Description | Example | +|----------|-------------|---------| +| `CACHE_SIZE_MB` | Cache size in MB | `512` | +| `CACHE_TYPE` | Cache implementation | `freecache` | + +--- + +## Dynamic Configuration (etcd Model Config) + +Model configurations are stored in etcd and hot-reloaded. Each model is identified by a `model_config_id`. + +### Config Structure + +```json +{ + "model_config_id_example": { + "dag_execution_config": { + "component_dependency": { + "feature_initializer": ["fs_user", "fs_product"], + "fs_user": ["ranker_model"], + "fs_product": ["ranker_model"], + "ranker_model": [] + } + }, + "component_config": { + "feature_component_config": { + "fs_user": { ... }, + "fs_product": { ... } + }, + "predator_component_config": { + "ranker_model": { ... } + }, + "numerix_component_config": {}, + "cache_enabled": true, + "cache_version": "v1", + "cache_ttl": 300, + "error_logging_percent": 10 + }, + "response_config": { + "features": ["ranker_model:score"], + "model_schema_perc": 100, + "logging_perc": 5, + "log_features": ["fs_user:profile:age", "ranker_model:score"], + "log_batch_size": 100 + } + } +} +``` + +--- + +### DAG Execution Config + +Defines the component dependency graph. + +```json +{ + "component_dependency": { + "": ["", ""], + "": [""], + "": [""], + "": [] + } +} +``` + +**Rules:** +- The graph must be a valid DAG (no cycles) +- Components with no parents (zero in-degree) execute first +- Components with empty dependency arrays `[]` are leaf nodes +- All component names must match registered components in the `ComponentConfig` + +--- + +### Feature Component Config + +Configures how features are fetched from the Online Feature Store. + +```json +{ + "fs_user": { + "fs_keys": { + "schema": ["user_id"], + "col": "context:user:user_id" + }, + "fs_request": { + "entity_label": "user", + "feature_groups": [ + { + "label": "demographics", + "feature_labels": ["age", "location", "income_bracket"] + }, + { + "label": "behavior", + "feature_labels": ["click_rate", "purchase_freq"] + } + ] + }, + "fs_flatten_resp_keys": ["user_id"], + "col_name_prefix": "user", + "comp_cache_enabled": true, + "comp_cache_ttl": 600, + "composite_id": false + } +} +``` + +| Field | Description | +|-------|-------------| +| `fs_keys` | How to extract lookup keys from the matrix. `schema` defines key column names; `col` references a matrix column | +| `fs_request` | OnFS query: entity label + feature groups with specific features | +| `fs_flatten_resp_keys` | Keys to flatten in response mapping | +| `col_name_prefix` | Prefix for matrix column names (e.g., `user:demographics:age`) | +| `comp_cache_enabled` | Enable in-memory caching for this component | +| `comp_cache_ttl` | Cache TTL in seconds | +| `composite_id` | Whether entity keys are composite | + +--- + +### Predator Component Config + +Configures model inference endpoints. + +```json +{ + "ranker_model": { + "model_name": "product_ranker_v3", + "model_endpoint": "predator-ranker:8080", + "model_end_points": { + "predator-ranker-v3:8080": 80, + "predator-ranker-v4:8080": 20 + }, + "deadline": 100, + "batch_size": 50, + "calibration": { + "enabled": false + }, + "inputs": { + "feature_map": { + "user:demographics:age": "INT32", + "user:behavior:click_rate": "FP32", + "product:attributes:category_id": "INT32" + } + }, + "outputs": { + "score_columns": ["score", "confidence"] + }, + "slate_component": false + } +} +``` + +| Field | Description | +|-------|-------------| +| `model_name` | Model identifier on the serving platform | +| `model_endpoint` | Primary model serving endpoint | +| `model_end_points` | Multiple endpoints with percentage-based traffic routing | +| `deadline` | Inference timeout in milliseconds | +| `batch_size` | Max items per inference batch | +| `calibration` | Score calibration settings | +| `inputs.feature_map` | Map of matrix column → data type for model input | +| `outputs.score_columns` | Column names for model output scores | +| `slate_component` | If true, runs per-slate inference | + +--- + +### Numerix Component Config + +Configures compute operations (e.g., reranking). + +```json +{ + "reranker": { + "score_column": "final_score", + "data_type": "FP32", + "score_mapping": { + "ranker_model:score": "FP32", + "user:behavior:click_rate": "FP32" + }, + "compute_id": "diversity_rerank_v1", + "slate_component": false + } +} +``` + +| Field | Description | +|-------|-------------| +| `score_column` | Output column name for the computed score | +| `data_type` | Output data type | +| `score_mapping` | Map of matrix columns to include as compute inputs | +| `compute_id` | Identifies the compute operation on Numerix | +| `slate_component` | If true, runs per-slate compute | + +--- + +### Response Config + +Controls what data is returned to the client and what is logged. + +```json +{ + "features": ["ranker_model:score", "reranker:final_score"], + "model_schema_perc": 100, + "logging_perc": 5, + "log_features": [ + "user:demographics:age", + "ranker_model:score", + "reranker:final_score" + ], + "log_batch_size": 100 +} +``` + +| Field | Description | +|-------|-------------| +| `features` | Matrix columns to include in the gRPC response | +| `model_schema_perc` | Percentage of requests that include full schema in response | +| `logging_perc` | Percentage of requests to send to Kafka for logging | +| `log_features` | Specific features to include in log messages | +| `log_batch_size` | Batch size for grouped log messages | + +--- + +### Service-Level Config + +Global settings that apply across all models. + +```json +{ + "v2_logging_type": "proto", + "compression_enabled": false +} +``` + +| Field | Values | Description | +|-------|--------|-------------| +| `v2_logging_type` | `proto`, `arrow`, `parquet` | Serialization format for Kafka inference logs | +| `compression_enabled` | `true`, `false` | Enable compression for log messages | + +--- + +## Example: Onboarding a New Model + +To onboard a new ranking model, update the etcd config: + +**Step 1:** Define the feature retrieval graph + +```json +"component_dependency": { + "feature_initializer": ["fs_user", "fs_product", "fs_user_x_category"], + "fs_product": ["fs_user_x_category"], + "fs_user": ["new_ranker"], + "fs_user_x_category": ["new_ranker"], + "new_ranker": [] +} +``` + +Here `fs_user_x_category` depends on `fs_product` because it needs the category ID extracted from the product entity to resolve the user x category key. + +**Step 2:** Configure each component (feature groups, model endpoints, etc.) + +**Step 3:** Push the config to etcd — Inferflow picks it up automatically via watchers. + +No code changes. No redeployment. The new model is live. + +--- + +## Contributing + +We welcome contributions from the community! Please see our [Contributing Guide](https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md) for details on how to get started. + +## Community & Support + +- **Discord**: Join our [community chat](https://discord.gg/XkT7XsV2AU) +- **Issues**: Report bugs and request features on [GitHub Issues](https://github.com/Meesho/BharatMLStack/issues) +- **Email**: Contact us at [ml-oss@meesho.com](mailto:ml-oss@meesho.com) + +## License + +BharatMLStack is open-source software licensed under the [BharatMLStack Business Source License 1.1](https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md). + +--- + +
+ Built with ❤️ for the ML community from Meesho +
+
+ If you find this useful, ⭐️ the repo — your support means the world to us! +
diff --git a/docs-src/docs/inferflow/v1.0.0/functionalities.md b/docs-src/docs/inferflow/v1.0.0/functionalities.md new file mode 100644 index 00000000..cb944b1b --- /dev/null +++ b/docs-src/docs/inferflow/v1.0.0/functionalities.md @@ -0,0 +1,309 @@ +--- +title: Key Functionalities +sidebar_position: 2 +--- + +# Inferflow - Key Functionalities + +## Overview + +Inferflow is a high-performance, config-driven ML inference orchestration engine built in **Go**. It provides **no-code feature retrieval**, **DAG-based execution**, and **multi-pattern model inference** — enabling ML teams to onboard new models through configuration changes alone. + +--- + +## Core Capabilities + +### Graph-Driven Feature Retrieval + +Inferflow's defining feature is its ability to resolve entity relationships and retrieve features through configurable DAG topologies — no custom code required. + +**How it works:** + +1. A `model_config_id` maps to a pre-defined DAG of components +2. Context entity IDs (e.g., `userId`, `productIds`) are provided at request time +3. The DAG resolves intermediate entity relationships (e.g., extracting `category` from `product` to fetch `user x category` features) +4. Features are fetched in parallel from the Online Feature Store +5. A 2D feature matrix is assembled and passed to model scoring + +**Impact:** +- New models require only a config update — no code changes +- Feature consistency is guaranteed across experiments +- Iteration cycles drop from days to minutes + +### DAG Topology Executor + +The execution engine uses **Kahn's algorithm** for topological ordering with **concurrent goroutine execution** at each level: + +``` +component_dependency: { + "feature_initializer": ["fs_user", "fs_product"], + "fs_user": ["ranker"], + "fs_product": ["ranker"], + "ranker": ["reranker"], + "reranker": [] +} +``` + +This config defines: +- `feature_initializer` runs first (zero in-degree) +- `fs_user` and `fs_product` run **in parallel** after init +- `ranker` runs after both feature components complete +- `reranker` runs after the ranker + +**Key properties:** +- Cycle detection via in-degree analysis +- DAG topologies cached using Murmur3 hashing (Ristretto cache) +- Components are registered and resolved via a `ComponentProvider` + +--- + +## Multi-Pattern Inference APIs + +Inferflow supports three inference patterns via the **Predict API**, each designed for different ML use cases: + +### PointWise Inference + +Score each target independently against context features. + +```protobuf +rpc InferPointWise(PredictRequest) returns (PredictResponse); +``` + +**Use cases:** Click-through rate prediction, fraud scoring, relevance ranking + +**Input:** Context features + list of targets (e.g., products) +**Output:** Per-target scores + +### PairWise Inference + +Score pairs of targets relative to each other. + +```protobuf +rpc InferPairWise(PredictRequest) returns (PredictResponse); +``` + +**Use cases:** Preference learning, comparison-based ranking + +**Input:** Context features + targets + pair indices (first/second) +**Output:** Per-pair scores + optional per-target scores + +### SlateWise Inference + +Score groups (slates) of targets together, capturing inter-item effects. + +```protobuf +rpc InferSlateWise(PredictRequest) returns (PredictResponse); +``` + +**Use cases:** Whole-page optimization, slate-level reranking, diversity-aware scoring + +**Input:** Context features + targets + slate definitions (target indices per slate) +**Output:** Per-slate scores + optional per-target scores + +--- + +## Entity & Legacy API + +### RetrieveModelScore + +The original Inferflow API for entity-based feature retrieval and scoring: + +```protobuf +service Inferflow { + rpc RetrieveModelScore(InferflowRequestProto) returns (InferflowResponseProto); +} +``` + +**Request structure:** + +| Field | Description | +|-------|-------------| +| `entities` | List of entity types with their IDs and optional inline features | +| `model_config_id` | Identifies the model configuration (DAG, components, response format) | +| `tracking_id` | Request-level tracing identifier | + +**Entity structure:** +- `entity`: Entity type label (e.g., `"user"`, `"product"`) +- `ids`: List of entity IDs +- `features`: Optional inline features (name + per-ID values) + +--- + +## Component Types + +### FeatureInitComponent + +**Role:** Root DAG node — initializes the shared `ComponentMatrix`. + +- Sets up rows from entity IDs +- Populates schema columns (string + byte) for all downstream components +- For slate APIs: initializes `SlateData` with `slate_target_indices` + +### FeatureComponent + +**Role:** Fetches features from the Online Feature Store (OnFS) for a specific entity type. + +- Reads `FSKeys` from config to extract lookup keys from the matrix +- Batches unique entities and calls OnFS via gRPC +- Optional **in-memory caching** keyed by `model_id:version:component:entity` +- Writes binary feature values into matrix byte columns + +**Column naming convention:** `entity_label:feature_group:feature_name` + +### PredatorComponent + +**Role:** Calls model serving endpoints for inference. + +- Builds feature payloads from matrix columns with type conversion +- Supports **percentage-based traffic routing** across multiple model endpoints +- Handles **slate-level inference**: per-slate matrix → separate inference → scores to `SlateData` +- Configurable **calibration** and **batch sizing** + +### NumerixComponent + +**Role:** Calls the Numerix compute engine for operations like reranking. + +- Uses `ScoreMapping` config to map matrix columns to compute inputs +- Writes a single score column back to the matrix +- Supports slate mode for per-slate compute operations + +--- + +## Feature Retrieval Pipeline + +### Key Resolution + +Feature components use `FSKeys` configuration to dynamically resolve entity keys: + +```json +{ + "FSKeys": { + "schema": ["user_id"], + "col": "user:profile:user_id" + } +} +``` + +The component reads key values from the existing matrix columns, enabling **chained entity resolution** — e.g., fetch product entity first, extract category, then fetch user x category features. + +### Batched Retrieval + +- Features are fetched via `FeatureService.RetrieveFeatures` gRPC call +- Requests are batched by unique entity keys +- Configurable batch size and deadline per component +- Auth via `CALLER_ID` and `CALLER_TOKEN` metadata + +### In-Memory Caching + +Optional per-component caching reduces OnFS load: + +- Cache key: `model_id:cache_version:component_name:entity_key` +- Configurable TTL per component +- Zero-GC-overhead cache implementation available +- Cache hit/miss metrics tracked via StatsD + +--- + +## Data Types + +Inferflow supports comprehensive ML data types for feature encoding and model input/output: + +| Data Type | Variants | Usage | +|-----------|----------|-------| +| **Integers** | int8, int16, int32, int64 | Categorical encodings, counts, IDs | +| **Floats** | float8 (e4m3, e5m2), float16, float32, float64 | Continuous features, embeddings, scores | +| **Strings** | Variable length | Categories, metadata | +| **Booleans** | Bit-packed | Binary indicators | +| **Vectors** | All scalar types | Embeddings, feature arrays | + +Type conversion is handled by the `datatypeconverter` package with optimized float8 implementations. + +--- + +## Inference Logging + +Inferflow supports async inference logging to Kafka for model monitoring and debugging: + +### Serialization Formats + +| Format | Use Case | +|--------|----------| +| **Proto** | Default, compact | +| **Arrow** | Columnar analytics | +| **Parquet** | Long-term storage, query-friendly | + +### Sampling Controls + +| Config | Description | +|--------|-------------| +| `LoggingPerc` | Percentage of requests to log (0-100) | +| `LogBatchSize` | Batch size for log message grouping | +| `LogFeatures` | Specific features to include in logs | + +### Log Content + +Each `InferflowLog` message includes: +- `user_id`, `tracking_id`, `model_config_id` +- Entity IDs and feature values +- Model scores and metadata + +--- + +## Configuration Hot-Reload + +Model configurations are stored in **etcd** and support **live updates without redeployment**: + +1. Inferflow registers watchers on etcd config paths +2. On config change, watchers trigger `ReloadModelConfigMapAndRegisterComponents` +3. `ConfigMap` is updated in memory +4. Feature schemas are re-initialized +5. DAG components are re-registered + +This enables: +- Adding new models in production without restarts +- A/B testing with different model configurations +- Instant rollback by reverting etcd config + +--- + +## Performance Characteristics + +### Concurrency Model +- DAG components at the same level execute concurrently in goroutines +- Feature retrieval is parallelized across entity types +- External gRPC calls use connection pooling + +### Memory Efficiency +- Built in Go — significantly lower memory footprint than Java equivalents (~80% reduction) +- Object pooling for `ComponentMatrix` and serialization buffers +- In-memory cache with zero-GC-overhead option (freecache) + +### Serialization +- gRPC with Proto3 for all external communication +- Binary feature encoding in the `ComponentMatrix` for minimal overhead +- Configurable compression for Kafka logging + +--- + +## Contributing + +We welcome contributions from the community! Please see our [Contributing Guide](https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md) for details on how to get started. + +## Community & Support + +- **Discord**: Join our [community chat](https://discord.gg/XkT7XsV2AU) +- **Issues**: Report bugs and request features on [GitHub Issues](https://github.com/Meesho/BharatMLStack/issues) +- **Email**: Contact us at [ml-oss@meesho.com](mailto:ml-oss@meesho.com) + +## License + +BharatMLStack is open-source software licensed under the [BharatMLStack Business Source License 1.1](https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md). + +--- + +
+ Built with ❤️ for the ML community from Meesho +
+
+ If you find this useful, ⭐️ the repo — your support means the world to us! +
diff --git a/docs-src/docs/inferflow/v1.0.0/release-notes.md b/docs-src/docs/inferflow/v1.0.0/release-notes.md new file mode 100644 index 00000000..2a73c843 --- /dev/null +++ b/docs-src/docs/inferflow/v1.0.0/release-notes.md @@ -0,0 +1,208 @@ +--- +title: Release Notes +sidebar_position: 4 +--- + +# Inferflow - Release Notes + +## Version 1.0.0 +**Release Date**: June 2025 +**Status**: General Availability (GA) + +We're excited to announce the first stable release of **Inferflow** — a graph-driven feature retrieval and model inference orchestration engine, part of BharatMLStack. + +--- + +## What's New + +### Config-Driven DAG Executor +- **No-code feature retrieval**: Onboard new models with config changes only — no custom code required +- **DAG topology execution**: Define component dependency graphs that are executed concurrently using Kahn's algorithm +- **Hot reload**: Model configurations stored in etcd are watched and reloaded live — no redeployment needed +- **DAG caching**: Topologies are cached using Murmur3 hashing with Ristretto for minimal overhead + +### Multi-Pattern Inference APIs +Three structured inference patterns via the Predict API: + +| API | Pattern | Use Case | +|-----|---------|----------| +| `InferPointWise` | Score each target independently | CTR prediction, fraud scoring | +| `InferPairWise` | Score pairs of targets | Preference learning, comparison ranking | +| `InferSlateWise` | Score groups of targets together | Whole-page optimization, diversity-aware ranking | + +Plus the entity-based `RetrieveModelScore` API for direct feature retrieval and scoring. + +### Component System +Four built-in component types: +- **FeatureInitComponent** — Initializes the shared ComponentMatrix +- **FeatureComponent** — Fetches features from the Online Feature Store (OnFS) +- **PredatorComponent** — Calls model serving endpoints with percentage-based traffic routing +- **NumerixComponent** — Calls compute engine for operations like reranking + +### Online Feature Store Integration +- gRPC-based feature retrieval via `FeatureService.RetrieveFeatures` +- Batched retrieval with configurable batch size and deadline +- Token-based authentication +- Dynamic key resolution from the ComponentMatrix + +### In-Memory Feature Caching +- Optional per-component caching to reduce OnFS load +- Configurable TTL per component +- Zero-GC-overhead cache option (freecache) +- Cache hit/miss metrics + +### Inference Logging +- Async logging to Kafka for model monitoring and debugging +- Three serialization formats: **Proto**, **Arrow**, **Parquet** +- Configurable sampling rate and feature selection +- Batched log message grouping + +--- + +## Performance + +### Built in Go +Inferflow is written entirely in Go, delivering: +- ~80% lower memory usage compared to equivalent Java services +- Lower CPU utilization +- Faster, more efficient deployments + +### Concurrency +- DAG components at the same level execute concurrently in goroutines +- Feature retrieval parallelized across entity types +- Connection pooling for all external gRPC calls + +### Serialization +- gRPC with Proto3 for all APIs +- Binary feature encoding in the ComponentMatrix +- Configurable compression for Kafka logging (ZSTD support) + +--- + +## APIs & Protocols + +### gRPC API + +**Inferflow Service:** +```protobuf +service Inferflow { + rpc RetrieveModelScore(InferflowRequestProto) returns (InferflowResponseProto); +} +``` + +**Predict Service:** +```protobuf +service PredictService { + rpc InferPointWise(PredictRequest) returns (PredictResponse); + rpc InferPairWise(PredictRequest) returns (PredictResponse); + rpc InferSlateWise(PredictRequest) returns (PredictResponse); +} +``` + +### Data Types Supported + +| Type | Variants | +|------|----------| +| Integers | int8, int16, int32, int64 | +| Floats | float8 (e4m3, e5m2), float16, float32, float64 | +| Strings | Variable length | +| Booleans | Bit-packed | +| Vectors | All scalar types | + +--- + +## Enterprise Features + +### Production Readiness +- **Health checks**: HTTP health endpoints via cmux +- **Graceful shutdown**: Clean resource cleanup +- **Structured logging**: JSON-formatted logs via zerolog +- **Signal handling**: SIGTERM/SIGINT support for container environments + +### Monitoring & Observability +- **StatsD / Telegraf integration**: Request rates, latencies, error rates +- **Per-component metrics**: Execution time, feature counts, cache hit rates +- **External API metrics**: OnFS, Predator, Numerix call tracking +- **Kafka logging metrics**: Messages sent, errors + +### Configuration Management +- **etcd-based**: All model configs stored in etcd +- **Watch & reload**: Live config updates without restart +- **Multi-model support**: Multiple `model_config_id` entries served concurrently + +--- + +## Deployment + +### Container Support +- **Docker image**: Multi-stage build (Go Alpine builder + Debian runtime) +- **Optional Kafka**: librdkafka support via build flag +- **Static binary**: Single binary deployment + +### Supported Environments +- Kubernetes (K8s) +- Google Kubernetes Engine (GKE) +- Amazon EKS + +--- + +## Compatibility + +### Supported Go Versions +- **Minimum**: Go 1.19 +- **Recommended**: Go 1.24+ + +### External Dependencies + +| Service | Version | Protocol | +|---------|---------|----------| +| etcd | 3.5+ | gRPC | +| Online Feature Store (OnFS) | 1.0+ | gRPC | +| Predator (Helix) | 1.0+ | gRPC | +| Numerix | 1.0+ | gRPC | +| Kafka | 2.0+ | TCP | + +--- + +## Download & Installation + +### Source Code +```bash +git clone https://github.com/Meesho/BharatMLStack.git +cd BharatMLStack/inferflow +``` + +### Build +```bash +go build -o inferflow-server cmd/inferflow/main.go +``` + +### Docker +```bash +docker build -t inferflow:latest . +``` + +--- + +## Contributing + +We welcome contributions from the community! Please see our [Contributing Guide](https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md) for details on how to get started. + +## Community & Support + +- **Discord**: Join our [community chat](https://discord.gg/XkT7XsV2AU) +- **Issues**: Report bugs and request features on [GitHub Issues](https://github.com/Meesho/BharatMLStack/issues) +- **Email**: Contact us at [ml-oss@meesho.com](mailto:ml-oss@meesho.com) + +## License + +BharatMLStack is open-source software licensed under the [BharatMLStack Business Source License 1.1](https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md). + +--- + +
+ Built with ❤️ for the ML community from Meesho +
+
+ If you find this useful, ⭐️ the repo — your support means the world to us! +
diff --git a/docs-src/package-lock.json b/docs-src/package-lock.json deleted file mode 100644 index c2617028..00000000 --- a/docs-src/package-lock.json +++ /dev/null @@ -1,17432 +0,0 @@ -{ - "name": "docs", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "docs", - "version": "0.0.0", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/preset-classic": "3.8.1", - "@mdx-js/react": "^3.0.0", - "clsx": "^2.0.0", - "prism-react-renderer": "^2.3.0", - "react": "^19.0.0", - "react-dom": "^19.0.0" - }, - "devDependencies": { - "@docusaurus/module-type-aliases": "3.8.1", - "@docusaurus/types": "3.8.1" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@algolia/autocomplete-core": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.9.tgz", - "integrity": "sha512-O7BxrpLDPJWWHv/DLA9DRFWs+iY1uOJZkqUwjS5HSZAGcl0hIVCQ97LTLewiZmZ402JYUrun+8NqFP+hCknlbQ==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.17.9", - "@algolia/autocomplete-shared": "1.17.9" - } - }, - "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.9.tgz", - "integrity": "sha512-u1fEHkCbWF92DBeB/KHeMacsjsoI0wFhjZtlCq2ddZbAehshbZST6Hs0Avkc0s+4UyBGbMDnSuXHLuvRWK5iDQ==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.17.9" - }, - "peerDependencies": { - "search-insights": ">= 1 < 3" - } - }, - "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.9.tgz", - "integrity": "sha512-Na1OuceSJeg8j7ZWn5ssMu/Ax3amtOwk76u4h5J4eK2Nx2KB5qt0Z4cOapCsxot9VcEN11ADV5aUSlQF4RhGjQ==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.17.9" - }, - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/autocomplete-shared": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.9.tgz", - "integrity": "sha512-iDf05JDQ7I0b7JEA/9IektxN/80a2MZ1ToohfmNS3rfeuQnIKI3IJlIafD0xu4StbtQTghx9T3Maa97ytkXenQ==", - "license": "MIT", - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/client-abtesting": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.27.0.tgz", - "integrity": "sha512-SITU5umoknxETtw67TxJu9njyMkWiH8pM+Bvw4dzfuIrIAT6Y1rmwV4y0A0didWoT+6xVuammIykbtBMolBcmg==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-analytics": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.27.0.tgz", - "integrity": "sha512-go1b9qIZK5vYEQ7jD2bsfhhhVsoh9cFxQ5xF8TzTsg2WOCZR3O92oXCkq15SOK0ngJfqDU6a/k0oZ4KuEnih1Q==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-common": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.27.0.tgz", - "integrity": "sha512-tnFOzdNuMzsz93kOClj3fKfuYoF3oYaEB5bggULSj075GJ7HUNedBEm7a6ScrjtnOaOtipbnT7veUpHA4o4wEQ==", - "license": "MIT", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-insights": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.27.0.tgz", - "integrity": "sha512-y1qgw39qZijjQBXrqZTiwK1cWgWGRiLpJNWBv9w36nVMKfl9kInrfsYmdBAfmlhVgF/+Woe0y1jQ7pa4HyShAw==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-personalization": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.27.0.tgz", - "integrity": "sha512-XluG9qPZKEbiLoIfXTKbABsWDNOMPx0t6T2ImJTTeuX+U/zBdmfcqqgcgkqXp+vbXof/XX/4of9Eqo1JaqEmKw==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-query-suggestions": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.27.0.tgz", - "integrity": "sha512-V8/To+SsAl2sdw2AAjeLJuCW1L+xpz+LAGerJK7HKqHzE5yQhWmIWZTzqYQcojkii4iBMYn0y3+uReWqT8XVSQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-search": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.27.0.tgz", - "integrity": "sha512-EJJ7WmvmUXZdchueKFCK8UZFyLqy4Hz64snNp0cTc7c0MKaSeDGYEDxVsIJKp15r7ORaoGxSyS4y6BGZMXYuCg==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/events": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", - "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==", - "license": "MIT" - }, - "node_modules/@algolia/ingestion": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.27.0.tgz", - "integrity": "sha512-xNCyWeqpmEo4EdmpG57Fs1fJIQcPwt5NnJ6MBdXnUdMVXF4f5PHgza+HQWQQcYpCsune96jfmR0v7us6gRIlCw==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/monitoring": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.27.0.tgz", - "integrity": "sha512-P0NDiEFyt9UYQLBI0IQocIT7xHpjMpoFN3UDeerbztlkH9HdqT0GGh1SHYmNWpbMWIGWhSJTtz6kSIWvFu4+pw==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/recommend": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.27.0.tgz", - "integrity": "sha512-cqfTMF1d1cc7hg0vITNAFxJZas7MJ4Obc36WwkKpY23NOtGb+4tH9X7UKlQa2PmTgbXIANoJ/DAQTeiVlD2I4Q==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-browser-xhr": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.27.0.tgz", - "integrity": "sha512-ErenYTcXl16wYXtf0pxLl9KLVxIztuehqXHfW9nNsD8mz9OX42HbXuPzT7y6JcPiWJpc/UU/LY5wBTB65vsEUg==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-fetch": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.27.0.tgz", - "integrity": "sha512-CNOvmXsVi+IvT7z1d+6X7FveVkgEQwTNgipjQCHTIbF9KSMfZR7tUsJC+NpELrm10ALdOMauah84ybs9rw1cKQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-node-http": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.27.0.tgz", - "integrity": "sha512-Nx9EdLYZDsaYFTthqmc0XcVvsx6jqeEX8fNiYOB5i2HboQwl8pJPj1jFhGqoGd0KG7KFR+sdPO5/e0EDDAru2Q==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.5.tgz", - "integrity": "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.4.tgz", - "integrity": "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==", - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.3", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.27.3", - "@babel/helpers": "^7.27.4", - "@babel/parser": "^7.27.4", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.27.4", - "@babel/types": "^7.27.3", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", - "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.27.5", - "@babel/types": "^7.27.3", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", - "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz", - "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-member-expression-to-functions": "^7.27.1", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.27.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", - "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "regexpu-core": "^6.2.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz", - "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==", - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", - "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", - "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", - "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", - "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-wrap-function": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", - "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", - "license": "MIT", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.27.1", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", - "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.27.1.tgz", - "integrity": "sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==", - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.1", - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", - "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.27.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz", - "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.3" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz", - "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", - "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", - "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", - "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.27.1.tgz", - "integrity": "sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", - "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", - "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.27.1.tgz", - "integrity": "sha512-eST9RrwlpaoJBDHShc+DS2SG4ATTi2MYNb4OxYkf3n+7eb49LWpnS+HSpVfW4x927qQwgk8A2hGNVaajAEw0EA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", - "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-remap-async-to-generator": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", - "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.5.tgz", - "integrity": "sha512-JF6uE2s67f0y2RZcm2kpAUEbD50vH62TyWVebxwHAlbSdM49VqPz8t4a1uIjp4NIOIZ4xzLfjY5emt/RCyC7TQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", - "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.27.1.tgz", - "integrity": "sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.27.1.tgz", - "integrity": "sha512-7iLhfFAubmpeJe/Wo2TVuDrykh/zlWXLzPNdL0Jqn/Xu8R3QQ8h9ff8FQoISZOsw74/HFqFI7NX63HN7QFIHKA==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-compilation-targets": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.27.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", - "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/template": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.27.3.tgz", - "integrity": "sha512-s4Jrok82JpiaIprtY2nHsYmrThKvvwgHwjgd7UMiYhZaN0asdXNLr0y+NjTfkA7SyQE5i2Fb7eawUOZmLvyqOA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", - "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", - "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", - "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz", - "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", - "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", - "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", - "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", - "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", - "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz", - "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", - "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", - "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", - "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz", - "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", - "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", - "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", - "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", - "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.27.3.tgz", - "integrity": "sha512-7ZZtznF9g4l2JCImCo5LNKFHB5eXnN39lLtLY5Tg+VkR0jwOt7TBciMckuiQIOIW7L5tkQOCh3bVGYeXgMx52Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.27.3", - "@babel/plugin-transform-parameters": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", - "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", - "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", - "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.1.tgz", - "integrity": "sha512-018KRk76HWKeZ5l4oTj2zPpSh+NbGdt0st5S6x0pga6HgrjBOJb24mMDHorFopOOd6YHkLgOZ+zaCjZGPO4aKg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", - "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", - "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", - "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz", - "integrity": "sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.27.1.tgz", - "integrity": "sha512-p9+Vl3yuHPmkirRrg021XiP+EETmPMQTLr6Ayjj85RLNEbb3Eya/4VI0vAdzQG9SEAl2Lnt7fy5lZyMzjYoZQQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz", - "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz", - "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==", - "license": "MIT", - "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz", - "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.5.tgz", - "integrity": "sha512-uhB8yHerfe3MWnuLAhEbeQ4afVoqv8BQsPqrTv7e/jZ9y00kJL6l9a/f4OWaKxotmjzewfEyXE1vgDJenkQ2/Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regexp-modifiers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", - "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", - "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.27.4.tgz", - "integrity": "sha512-D68nR5zxU64EUzV8i7T3R5XP0Xhrou/amNnddsRQssx6GrTLdZl1rLxyjtVZBd+v/NVX4AbTPOB5aU8thAZV1A==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.11.0", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", - "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", - "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", - "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", - "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", - "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.27.1.tgz", - "integrity": "sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", - "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", - "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", - "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", - "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.27.2.tgz", - "integrity": "sha512-Ma4zSuYSlGNRlCLO+EAzLnCmJK2vdstgv+n7aUP+/IKZrOfWHOJVdSJtuub8RzHTj3ahD37k5OKJWvzf16TQyQ==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.27.1", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-import-assertions": "^7.27.1", - "@babel/plugin-syntax-import-attributes": "^7.27.1", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.27.1", - "@babel/plugin-transform-async-generator-functions": "^7.27.1", - "@babel/plugin-transform-async-to-generator": "^7.27.1", - "@babel/plugin-transform-block-scoped-functions": "^7.27.1", - "@babel/plugin-transform-block-scoping": "^7.27.1", - "@babel/plugin-transform-class-properties": "^7.27.1", - "@babel/plugin-transform-class-static-block": "^7.27.1", - "@babel/plugin-transform-classes": "^7.27.1", - "@babel/plugin-transform-computed-properties": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.27.1", - "@babel/plugin-transform-dotall-regex": "^7.27.1", - "@babel/plugin-transform-duplicate-keys": "^7.27.1", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", - "@babel/plugin-transform-dynamic-import": "^7.27.1", - "@babel/plugin-transform-exponentiation-operator": "^7.27.1", - "@babel/plugin-transform-export-namespace-from": "^7.27.1", - "@babel/plugin-transform-for-of": "^7.27.1", - "@babel/plugin-transform-function-name": "^7.27.1", - "@babel/plugin-transform-json-strings": "^7.27.1", - "@babel/plugin-transform-literals": "^7.27.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", - "@babel/plugin-transform-member-expression-literals": "^7.27.1", - "@babel/plugin-transform-modules-amd": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-modules-systemjs": "^7.27.1", - "@babel/plugin-transform-modules-umd": "^7.27.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", - "@babel/plugin-transform-new-target": "^7.27.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", - "@babel/plugin-transform-numeric-separator": "^7.27.1", - "@babel/plugin-transform-object-rest-spread": "^7.27.2", - "@babel/plugin-transform-object-super": "^7.27.1", - "@babel/plugin-transform-optional-catch-binding": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.27.1", - "@babel/plugin-transform-parameters": "^7.27.1", - "@babel/plugin-transform-private-methods": "^7.27.1", - "@babel/plugin-transform-private-property-in-object": "^7.27.1", - "@babel/plugin-transform-property-literals": "^7.27.1", - "@babel/plugin-transform-regenerator": "^7.27.1", - "@babel/plugin-transform-regexp-modifiers": "^7.27.1", - "@babel/plugin-transform-reserved-words": "^7.27.1", - "@babel/plugin-transform-shorthand-properties": "^7.27.1", - "@babel/plugin-transform-spread": "^7.27.1", - "@babel/plugin-transform-sticky-regex": "^7.27.1", - "@babel/plugin-transform-template-literals": "^7.27.1", - "@babel/plugin-transform-typeof-symbol": "^7.27.1", - "@babel/plugin-transform-unicode-escapes": "^7.27.1", - "@babel/plugin-transform-unicode-property-regex": "^7.27.1", - "@babel/plugin-transform-unicode-regex": "^7.27.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.11.0", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.40.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/preset-react": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.27.1.tgz", - "integrity": "sha512-oJHWh2gLhU9dW9HHr42q0cI0/iHHXTLGe39qvpAZZzagHy0MzYLCnCVV0symeRvzmjHyVU7mw2K06E6u/JwbhA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-transform-react-display-name": "^7.27.1", - "@babel/plugin-transform-react-jsx": "^7.27.1", - "@babel/plugin-transform-react-jsx-development": "^7.27.1", - "@babel/plugin-transform-react-pure-annotations": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz", - "integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-typescript": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", - "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.27.6.tgz", - "integrity": "sha512-vDVrlmRAY8z9Ul/HxT+8ceAru95LQgkSKiXkSYZvqtbkPSfhZJgpRp45Cldbh1GJ1kxzQkI70AqyrTI58KpaWQ==", - "license": "MIT", - "dependencies": { - "core-js-pure": "^3.30.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz", - "integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.3", - "@babel/parser": "^7.27.4", - "@babel/template": "^7.27.2", - "@babel/types": "^7.27.3", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz", - "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@csstools/cascade-layer-name-parser": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.5.tgz", - "integrity": "sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/color-helpers": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", - "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - } - }, - "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-color-parser": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.10.tgz", - "integrity": "sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/color-helpers": "^5.0.2", - "@csstools/css-calc": "^2.1.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@csstools/media-query-list-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", - "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/postcss-cascade-layers": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.1.tgz", - "integrity": "sha512-XOfhI7GShVcKiKwmPAnWSqd2tBR0uxt+runAxttbSp/LY2U16yAVPmAf7e9q4JJ0d+xMNmpwNDLBXnmRCl3HMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/selector-specificity": "^5.0.0", - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-cascade-layers/node_modules/@csstools/selector-specificity": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" - } - }, - "node_modules/@csstools/postcss-cascade-layers/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@csstools/postcss-color-function": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-4.0.10.tgz", - "integrity": "sha512-4dY0NBu7NVIpzxZRgh/Q/0GPSz/jLSw0i/u3LTUor0BkQcz/fNhN10mSWBDsL0p9nDb0Ky1PD6/dcGbhACuFTQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-color-mix-function": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.10.tgz", - "integrity": "sha512-P0lIbQW9I4ShE7uBgZRib/lMTf9XMjJkFl/d6w4EMNHu2qvQ6zljJGEcBkw/NsBtq/6q3WrmgxSS8kHtPMkK4Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-color-mix-variadic-function-arguments": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-variadic-function-arguments/-/postcss-color-mix-variadic-function-arguments-1.0.0.tgz", - "integrity": "sha512-Z5WhouTyD74dPFPrVE7KydgNS9VvnjB8qcdes9ARpCOItb4jTnm7cHp4FhxCRUoyhabD0WVv43wbkJ4p8hLAlQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-content-alt-text": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.6.tgz", - "integrity": "sha512-eRjLbOjblXq+byyaedQRSrAejKGNAFued+LcbzT+LCL78fabxHkxYjBbxkroONxHHYu2qxhFK2dBStTLPG3jpQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-exponential-functions": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.9.tgz", - "integrity": "sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-font-format-keywords": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-4.0.0.tgz", - "integrity": "sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-gamut-mapping": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.10.tgz", - "integrity": "sha512-QDGqhJlvFnDlaPAfCYPsnwVA6ze+8hhrwevYWlnUeSjkkZfBpcCO42SaUD8jiLlq7niouyLgvup5lh+f1qessg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-gradients-interpolation-method": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.10.tgz", - "integrity": "sha512-HHPauB2k7Oits02tKFUeVFEU2ox/H3OQVrP3fSOKDxvloOikSal+3dzlyTZmYsb9FlY9p5EUpBtz0//XBmy+aw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-hwb-function": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.10.tgz", - "integrity": "sha512-nOKKfp14SWcdEQ++S9/4TgRKchooLZL0TUFdun3nI4KPwCjETmhjta1QT4ICQcGVWQTvrsgMM/aLB5We+kMHhQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-ic-unit": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.2.tgz", - "integrity": "sha512-lrK2jjyZwh7DbxaNnIUjkeDmU8Y6KyzRBk91ZkI5h8nb1ykEfZrtIVArdIjX4DHMIBGpdHrgP0n4qXDr7OHaKA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-initial": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-initial/-/postcss-initial-2.0.1.tgz", - "integrity": "sha512-L1wLVMSAZ4wovznquK0xmC7QSctzO4D0Is590bxpGqhqjboLXYA16dWZpfwImkdOgACdQ9PqXsuRroW6qPlEsg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-is-pseudo-class": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.3.tgz", - "integrity": "sha512-jS/TY4SpG4gszAtIg7Qnf3AS2pjcUM5SzxpApOrlndMeGhIbaTzWBzzP/IApXoNWEW7OhcjkRT48jnAUIFXhAQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/selector-specificity": "^5.0.0", - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-is-pseudo-class/node_modules/@csstools/selector-specificity": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" - } - }, - "node_modules/@csstools/postcss-is-pseudo-class/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@csstools/postcss-light-dark-function": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.9.tgz", - "integrity": "sha512-1tCZH5bla0EAkFAI2r0H33CDnIBeLUaJh1p+hvvsylJ4svsv2wOmJjJn+OXwUZLXef37GYbRIVKX+X+g6m+3CQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-logical-float-and-clear": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-3.0.0.tgz", - "integrity": "sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-logical-overflow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overflow/-/postcss-logical-overflow-2.0.0.tgz", - "integrity": "sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-logical-overscroll-behavior": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overscroll-behavior/-/postcss-logical-overscroll-behavior-2.0.0.tgz", - "integrity": "sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-logical-resize": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-resize/-/postcss-logical-resize-3.0.0.tgz", - "integrity": "sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-logical-viewport-units": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.4.tgz", - "integrity": "sha512-q+eHV1haXA4w9xBwZLKjVKAWn3W2CMqmpNpZUk5kRprvSiBEGMgrNH3/sJZ8UA3JgyHaOt3jwT9uFa4wLX4EqQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-media-minmax": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.9.tgz", - "integrity": "sha512-af9Qw3uS3JhYLnCbqtZ9crTvvkR+0Se+bBqSr7ykAnl9yKhk6895z9rf+2F4dClIDJWxgn0iZZ1PSdkhrbs2ig==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/media-query-list-parser": "^4.0.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-media-queries-aspect-ratio-number-values": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.5.tgz", - "integrity": "sha512-zhAe31xaaXOY2Px8IYfoVTB3wglbJUVigGphFLj6exb7cjZRH9A6adyE22XfFK3P2PzwRk0VDeTJmaxpluyrDg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/media-query-list-parser": "^4.0.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-nested-calc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-4.0.0.tgz", - "integrity": "sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-normalize-display-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.0.tgz", - "integrity": "sha512-HlEoG0IDRoHXzXnkV4in47dzsxdsjdz6+j7MLjaACABX2NfvjFS6XVAnpaDyGesz9gK2SC7MbNwdCHusObKJ9Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-oklab-function": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.10.tgz", - "integrity": "sha512-ZzZUTDd0fgNdhv8UUjGCtObPD8LYxMH+MJsW9xlZaWTV8Ppr4PtxlHYNMmF4vVWGl0T6f8tyWAKjoI6vePSgAg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-progressive-custom-properties": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.1.0.tgz", - "integrity": "sha512-YrkI9dx8U4R8Sz2EJaoeD9fI7s7kmeEBfmO+UURNeL6lQI7VxF6sBE+rSqdCBn4onwqmxFdBU3lTwyYb/lCmxA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-random-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-random-function/-/postcss-random-function-2.0.1.tgz", - "integrity": "sha512-q+FQaNiRBhnoSNo+GzqGOIBKoHQ43lYz0ICrV+UudfWnEF6ksS6DsBIJSISKQT2Bvu3g4k6r7t0zYrk5pDlo8w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-relative-color-syntax": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.10.tgz", - "integrity": "sha512-8+0kQbQGg9yYG8hv0dtEpOMLwB9M+P7PhacgIzVzJpixxV4Eq9AUQtQw8adMmAJU1RBBmIlpmtmm3XTRd/T00g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-scope-pseudo-class": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-4.0.1.tgz", - "integrity": "sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-scope-pseudo-class/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@csstools/postcss-sign-functions": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.4.tgz", - "integrity": "sha512-P97h1XqRPcfcJndFdG95Gv/6ZzxUBBISem0IDqPZ7WMvc/wlO+yU0c5D/OCpZ5TJoTt63Ok3knGk64N+o6L2Pg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-stepped-value-functions": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.9.tgz", - "integrity": "sha512-h9btycWrsex4dNLeQfyU3y3w40LMQooJWFMm/SK9lrKguHDcFl4VMkncKKoXi2z5rM9YGWbUQABI8BT2UydIcA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-text-decoration-shorthand": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.2.tgz", - "integrity": "sha512-8XvCRrFNseBSAGxeaVTaNijAu+FzUvjwFXtcrynmazGb/9WUdsPCpBX+mHEHShVRq47Gy4peYAoxYs8ltUnmzA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/color-helpers": "^5.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-trigonometric-functions": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.9.tgz", - "integrity": "sha512-Hnh5zJUdpNrJqK9v1/E3BbrQhaDTj5YiX7P61TOvUhoDHnUmsNNxcDAgkQ32RrcWx9GVUvfUNPcUkn8R3vIX6A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-unset-value": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-4.0.0.tgz", - "integrity": "sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/utilities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@csstools/utilities/-/utilities-2.0.0.tgz", - "integrity": "sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@docsearch/css": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.9.0.tgz", - "integrity": "sha512-cQbnVbq0rrBwNAKegIac/t6a8nWoUAn8frnkLFW6YARaRmAQr5/Eoe6Ln2fqkUCZ40KpdrKbpSAmgrkviOxuWA==", - "license": "MIT" - }, - "node_modules/@docsearch/react": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.9.0.tgz", - "integrity": "sha512-mb5FOZYZIkRQ6s/NWnM98k879vu5pscWqTLubLFBO87igYYT4VzVazh4h5o/zCvTIZgEt3PvsCOMOswOUo9yHQ==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-core": "1.17.9", - "@algolia/autocomplete-preset-algolia": "1.17.9", - "@docsearch/css": "3.9.0", - "algoliasearch": "^5.14.2" - }, - "peerDependencies": { - "@types/react": ">= 16.8.0 < 20.0.0", - "react": ">= 16.8.0 < 20.0.0", - "react-dom": ">= 16.8.0 < 20.0.0", - "search-insights": ">= 1 < 3" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "search-insights": { - "optional": true - } - } - }, - "node_modules/@docusaurus/babel": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.8.1.tgz", - "integrity": "sha512-3brkJrml8vUbn9aeoZUlJfsI/GqyFcDgQJwQkmBtclJgWDEQBKKeagZfOgx0WfUQhagL1sQLNW0iBdxnI863Uw==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.25.9", - "@babel/generator": "^7.25.9", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.25.9", - "@babel/preset-env": "^7.25.9", - "@babel/preset-react": "^7.25.9", - "@babel/preset-typescript": "^7.25.9", - "@babel/runtime": "^7.25.9", - "@babel/runtime-corejs3": "^7.25.9", - "@babel/traverse": "^7.25.9", - "@docusaurus/logger": "3.8.1", - "@docusaurus/utils": "3.8.1", - "babel-plugin-dynamic-import-node": "^2.3.3", - "fs-extra": "^11.1.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/bundler": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.8.1.tgz", - "integrity": "sha512-/z4V0FRoQ0GuSLToNjOSGsk6m2lQUG4FRn8goOVoZSRsTrU8YR2aJacX5K3RG18EaX9b+52pN4m1sL3MQZVsQA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.25.9", - "@docusaurus/babel": "3.8.1", - "@docusaurus/cssnano-preset": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "babel-loader": "^9.2.1", - "clean-css": "^5.3.3", - "copy-webpack-plugin": "^11.0.0", - "css-loader": "^6.11.0", - "css-minimizer-webpack-plugin": "^5.0.1", - "cssnano": "^6.1.2", - "file-loader": "^6.2.0", - "html-minifier-terser": "^7.2.0", - "mini-css-extract-plugin": "^2.9.2", - "null-loader": "^4.0.1", - "postcss": "^8.5.4", - "postcss-loader": "^7.3.4", - "postcss-preset-env": "^10.2.1", - "terser-webpack-plugin": "^5.3.9", - "tslib": "^2.6.0", - "url-loader": "^4.1.1", - "webpack": "^5.95.0", - "webpackbar": "^6.0.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/faster": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/faster": { - "optional": true - } - } - }, - "node_modules/@docusaurus/core": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.8.1.tgz", - "integrity": "sha512-ENB01IyQSqI2FLtOzqSI3qxG2B/jP4gQPahl2C3XReiLebcVh5B5cB9KYFvdoOqOWPyr5gXK4sjgTKv7peXCrA==", - "license": "MIT", - "dependencies": { - "@docusaurus/babel": "3.8.1", - "@docusaurus/bundler": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "boxen": "^6.2.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "cli-table3": "^0.6.3", - "combine-promises": "^1.1.0", - "commander": "^5.1.0", - "core-js": "^3.31.1", - "detect-port": "^1.5.1", - "escape-html": "^1.0.3", - "eta": "^2.2.0", - "eval": "^0.1.8", - "execa": "5.1.1", - "fs-extra": "^11.1.1", - "html-tags": "^3.3.1", - "html-webpack-plugin": "^5.6.0", - "leven": "^3.1.0", - "lodash": "^4.17.21", - "open": "^8.4.0", - "p-map": "^4.0.0", - "prompts": "^2.4.2", - "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.4", - "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.4", - "semver": "^7.5.4", - "serve-handler": "^6.1.6", - "tinypool": "^1.0.2", - "tslib": "^2.6.0", - "update-notifier": "^6.0.2", - "webpack": "^5.95.0", - "webpack-bundle-analyzer": "^4.10.2", - "webpack-dev-server": "^4.15.2", - "webpack-merge": "^6.0.1" - }, - "bin": { - "docusaurus": "bin/docusaurus.mjs" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@mdx-js/react": "^3.0.0", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/cssnano-preset": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.8.1.tgz", - "integrity": "sha512-G7WyR2N6SpyUotqhGznERBK+x84uyhfMQM2MmDLs88bw4Flom6TY46HzkRkSEzaP9j80MbTN8naiL1fR17WQug==", - "license": "MIT", - "dependencies": { - "cssnano-preset-advanced": "^6.1.2", - "postcss": "^8.5.4", - "postcss-sort-media-queries": "^5.2.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/logger": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.8.1.tgz", - "integrity": "sha512-2wjeGDhKcExEmjX8k1N/MRDiPKXGF2Pg+df/bDDPnnJWHXnVEZxXj80d6jcxp1Gpnksl0hF8t/ZQw9elqj2+ww==", - "license": "MIT", - "dependencies": { - "chalk": "^4.1.2", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/mdx-loader": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.8.1.tgz", - "integrity": "sha512-DZRhagSFRcEq1cUtBMo4TKxSNo/W6/s44yhr8X+eoXqCLycFQUylebOMPseHi5tc4fkGJqwqpWJLz6JStU9L4w==", - "license": "MIT", - "dependencies": { - "@docusaurus/logger": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "@mdx-js/mdx": "^3.0.0", - "@slorber/remark-comment": "^1.0.0", - "escape-html": "^1.0.3", - "estree-util-value-to-estree": "^3.0.1", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "image-size": "^2.0.2", - "mdast-util-mdx": "^3.0.0", - "mdast-util-to-string": "^4.0.0", - "rehype-raw": "^7.0.0", - "remark-directive": "^3.0.0", - "remark-emoji": "^4.0.0", - "remark-frontmatter": "^5.0.0", - "remark-gfm": "^4.0.0", - "stringify-object": "^3.3.0", - "tslib": "^2.6.0", - "unified": "^11.0.3", - "unist-util-visit": "^5.0.0", - "url-loader": "^4.1.1", - "vfile": "^6.0.1", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/module-type-aliases": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.8.1.tgz", - "integrity": "sha512-6xhvAJiXzsaq3JdosS7wbRt/PwEPWHr9eM4YNYqVlbgG1hSK3uQDXTVvQktasp3VO6BmfYWPozueLWuj4gB+vg==", - "license": "MIT", - "dependencies": { - "@docusaurus/types": "3.8.1", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "@types/react-router-dom": "*", - "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/@docusaurus/plugin-content-blog": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.8.1.tgz", - "integrity": "sha512-vNTpMmlvNP9n3hGEcgPaXyvTljanAKIUkuG9URQ1DeuDup0OR7Ltvoc8yrmH+iMZJbcQGhUJF+WjHLwuk8HSdw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "cheerio": "1.0.0-rc.12", - "feed": "^4.2.2", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "schema-dts": "^1.1.2", - "srcset": "^4.0.0", - "tslib": "^2.6.0", - "unist-util-visit": "^5.0.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/plugin-content-docs": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.8.1.tgz", - "integrity": "sha512-oByRkSZzeGNQByCMaX+kif5Nl2vmtj2IHQI2fWjCfCootsdKZDPFLonhIp5s3IGJO7PLUfe0POyw0Xh/RrGXJA==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/module-type-aliases": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "@types/react-router-config": "^5.0.7", - "combine-promises": "^1.1.0", - "fs-extra": "^11.1.1", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "schema-dts": "^1.1.2", - "tslib": "^2.6.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-pages": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.8.1.tgz", - "integrity": "sha512-a+V6MS2cIu37E/m7nDJn3dcxpvXb6TvgdNI22vJX8iUTp8eoMoPa0VArEbWvCxMY/xdC26WzNv4wZ6y0iIni/w==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "fs-extra": "^11.1.1", - "tslib": "^2.6.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-css-cascade-layers": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.8.1.tgz", - "integrity": "sha512-VQ47xRxfNKjHS5ItzaVXpxeTm7/wJLFMOPo1BkmoMG4Cuz4nuI+Hs62+RMk1OqVog68Swz66xVPK8g9XTrBKRw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/plugin-debug": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.8.1.tgz", - "integrity": "sha512-nT3lN7TV5bi5hKMB7FK8gCffFTBSsBsAfV84/v293qAmnHOyg1nr9okEw8AiwcO3bl9vije5nsUvP0aRl2lpaw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "fs-extra": "^11.1.1", - "react-json-view-lite": "^2.3.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.8.1.tgz", - "integrity": "sha512-Hrb/PurOJsmwHAsfMDH6oVpahkEGsx7F8CWMjyP/dw1qjqmdS9rcV1nYCGlM8nOtD3Wk/eaThzUB5TSZsGz+7Q==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-gtag": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.8.1.tgz", - "integrity": "sha512-tKE8j1cEZCh8KZa4aa80zpSTxsC2/ZYqjx6AAfd8uA8VHZVw79+7OTEP2PoWi0uL5/1Is0LF5Vwxd+1fz5HlKg==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "@types/gtag.js": "^0.0.12", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-tag-manager": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.8.1.tgz", - "integrity": "sha512-iqe3XKITBquZq+6UAXdb1vI0fPY5iIOitVjPQ581R1ZKpHr0qe+V6gVOrrcOHixPDD/BUKdYwkxFjpNiEN+vBw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-sitemap": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.8.1.tgz", - "integrity": "sha512-+9YV/7VLbGTq8qNkjiugIelmfUEVkTyLe6X8bWq7K5qPvGXAjno27QAfFq63mYfFFbJc7z+pudL63acprbqGzw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "fs-extra": "^11.1.1", - "sitemap": "^7.1.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-svgr": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-svgr/-/plugin-svgr-3.8.1.tgz", - "integrity": "sha512-rW0LWMDsdlsgowVwqiMb/7tANDodpy1wWPwCcamvhY7OECReN3feoFwLjd/U4tKjNY3encj0AJSTxJA+Fpe+Gw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "@svgr/core": "8.1.0", - "@svgr/webpack": "^8.1.0", - "tslib": "^2.6.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/preset-classic": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.8.1.tgz", - "integrity": "sha512-yJSjYNHXD8POMGc2mKQuj3ApPrN+eG0rO1UPgSx7jySpYU+n4WjBikbrA2ue5ad9A7aouEtMWUoiSRXTH/g7KQ==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/plugin-content-blog": "3.8.1", - "@docusaurus/plugin-content-docs": "3.8.1", - "@docusaurus/plugin-content-pages": "3.8.1", - "@docusaurus/plugin-css-cascade-layers": "3.8.1", - "@docusaurus/plugin-debug": "3.8.1", - "@docusaurus/plugin-google-analytics": "3.8.1", - "@docusaurus/plugin-google-gtag": "3.8.1", - "@docusaurus/plugin-google-tag-manager": "3.8.1", - "@docusaurus/plugin-sitemap": "3.8.1", - "@docusaurus/plugin-svgr": "3.8.1", - "@docusaurus/theme-classic": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/theme-search-algolia": "3.8.1", - "@docusaurus/types": "3.8.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/theme-classic": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.8.1.tgz", - "integrity": "sha512-bqDUCNqXeYypMCsE1VcTXSI1QuO4KXfx8Cvl6rYfY0bhhqN6d2WZlRkyLg/p6pm+DzvanqHOyYlqdPyP0iz+iw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/module-type-aliases": "3.8.1", - "@docusaurus/plugin-content-blog": "3.8.1", - "@docusaurus/plugin-content-docs": "3.8.1", - "@docusaurus/plugin-content-pages": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/theme-translations": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "@mdx-js/react": "^3.0.0", - "clsx": "^2.0.0", - "copy-text-to-clipboard": "^3.2.0", - "infima": "0.2.0-alpha.45", - "lodash": "^4.17.21", - "nprogress": "^0.2.0", - "postcss": "^8.5.4", - "prism-react-renderer": "^2.3.0", - "prismjs": "^1.29.0", - "react-router-dom": "^5.3.4", - "rtlcss": "^4.1.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/theme-common": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.8.1.tgz", - "integrity": "sha512-UswMOyTnPEVRvN5Qzbo+l8k4xrd5fTFu2VPPfD6FcW/6qUtVLmJTQCktbAL3KJ0BVXGm5aJXz/ZrzqFuZERGPw==", - "license": "MIT", - "dependencies": { - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/module-type-aliases": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "clsx": "^2.0.0", - "parse-numeric-range": "^1.3.0", - "prism-react-renderer": "^2.3.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/plugin-content-docs": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/theme-search-algolia": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.8.1.tgz", - "integrity": "sha512-NBFH5rZVQRAQM087aYSRKQ9yGEK9eHd+xOxQjqNpxMiV85OhJDD4ZGz6YJIod26Fbooy54UWVdzNU0TFeUUUzQ==", - "license": "MIT", - "dependencies": { - "@docsearch/react": "^3.9.0", - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/plugin-content-docs": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/theme-translations": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "algoliasearch": "^5.17.1", - "algoliasearch-helper": "^3.22.6", - "clsx": "^2.0.0", - "eta": "^2.2.0", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/theme-translations": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.8.1.tgz", - "integrity": "sha512-OTp6eebuMcf2rJt4bqnvuwmm3NVXfzfYejL+u/Y1qwKhZPrjPoKWfk1CbOP5xH5ZOPkiAsx4dHdQBRJszK3z2g==", - "license": "MIT", - "dependencies": { - "fs-extra": "^11.1.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/types": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.8.1.tgz", - "integrity": "sha512-ZPdW5AB+pBjiVrcLuw3dOS6BFlrG0XkS2lDGsj8TizcnREQg3J8cjsgfDviszOk4CweNfwo1AEELJkYaMUuOPg==", - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.95.0", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/types/node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@docusaurus/utils": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.8.1.tgz", - "integrity": "sha512-P1ml0nvOmEFdmu0smSXOqTS1sxU5tqvnc0dA4MTKV39kye+bhQnjkIKEE18fNOvxjyB86k8esoCIFM3x4RykOQ==", - "license": "MIT", - "dependencies": { - "@docusaurus/logger": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "escape-string-regexp": "^4.0.0", - "execa": "5.1.1", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "github-slugger": "^1.5.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "jiti": "^1.20.0", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "p-queue": "^6.6.2", - "prompts": "^2.4.2", - "resolve-pathname": "^3.0.0", - "tslib": "^2.6.0", - "url-loader": "^4.1.1", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/utils-common": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.8.1.tgz", - "integrity": "sha512-zTZiDlvpvoJIrQEEd71c154DkcriBecm4z94OzEE9kz7ikS3J+iSlABhFXM45mZ0eN5pVqqr7cs60+ZlYLewtg==", - "license": "MIT", - "dependencies": { - "@docusaurus/types": "3.8.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/utils-validation": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.8.1.tgz", - "integrity": "sha512-gs5bXIccxzEbyVecvxg6upTwaUbfa0KMmTj7HhHzc016AGyxH2o73k1/aOD0IFrdCsfJNt37MqNI47s2MgRZMA==", - "license": "MIT", - "dependencies": { - "@docusaurus/logger": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "fs-extra": "^11.2.0", - "joi": "^17.9.2", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", - "license": "MIT" - }, - "node_modules/@mdx-js/mdx": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.0.tgz", - "integrity": "sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdx": "^2.0.0", - "collapse-white-space": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-scope": "^1.0.0", - "estree-walker": "^3.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "markdown-extensions": "^2.0.0", - "recma-build-jsx": "^1.0.0", - "recma-jsx": "^1.0.0", - "recma-stringify": "^1.0.0", - "rehype-recma": "^1.0.0", - "remark-mdx": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "source-map": "^0.7.0", - "unified": "^11.0.0", - "unist-util-position-from-estree": "^2.0.0", - "unist-util-stringify-position": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/react": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", - "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", - "license": "MIT", - "dependencies": { - "@types/mdx": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@types/react": ">=16", - "react": ">=16" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", - "license": "MIT", - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", - "license": "MIT", - "dependencies": { - "graceful-fs": "4.2.10" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "license": "ISC" - }, - "node_modules/@pnpm/npm-conf": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", - "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", - "license": "MIT", - "dependencies": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.29", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", - "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", - "license": "MIT" - }, - "node_modules/@sideway/address": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", - "license": "BSD-3-Clause" - }, - "node_modules/@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "license": "MIT" - }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@slorber/remark-comment": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", - "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.1.0", - "micromark-util-symbol": "^1.0.1" - } - }, - "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", - "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", - "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", - "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", - "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", - "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", - "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-preset": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", - "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", - "license": "MIT", - "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", - "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", - "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", - "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", - "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", - "@svgr/babel-plugin-transform-svg-component": "8.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/core": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", - "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^8.1.3", - "snake-case": "^3.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", - "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.21.3", - "entities": "^4.4.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/plugin-jsx": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", - "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "@svgr/hast-util-to-babel-ast": "8.0.0", - "svg-parser": "^2.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@svgr/plugin-svgo": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", - "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", - "license": "MIT", - "dependencies": { - "cosmiconfig": "^8.1.3", - "deepmerge": "^4.3.1", - "svgo": "^3.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@svgr/webpack": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", - "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.21.3", - "@babel/plugin-transform-react-constant-elements": "^7.21.3", - "@babel/preset-env": "^7.20.2", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.21.0", - "@svgr/core": "8.1.0", - "@svgr/plugin-jsx": "8.1.0", - "@svgr/plugin-svgo": "8.1.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "license": "MIT", - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "license": "ISC", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "license": "MIT", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "license": "MIT" - }, - "node_modules/@types/estree-jsx": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", - "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", - "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz", - "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/express/node_modules/@types/express-serve-static-core": { - "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/gtag.js": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", - "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==", - "license": "MIT" - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", - "license": "MIT" - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "license": "MIT" - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", - "license": "MIT" - }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", - "license": "MIT" - }, - "node_modules/@types/http-proxy": { - "version": "1.17.16", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz", - "integrity": "sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdx": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", - "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", - "license": "MIT" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "24.0.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.1.tgz", - "integrity": "sha512-MX4Zioh39chHlDJbKmEgydJDS3tspMP/lnQC67G3SWsTnb9NeYVWOjkxpOSy4oMfPs4StcWHwBrvUb4ybfnuaw==", - "license": "MIT", - "dependencies": { - "undici-types": "~7.8.0" - } - }, - "node_modules/@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/prismjs": { - "version": "1.26.5", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.5.tgz", - "integrity": "sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==", - "license": "MIT" - }, - "node_modules/@types/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "19.1.8", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", - "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", - "license": "MIT", - "dependencies": { - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-router": { - "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*" - } - }, - "node_modules/@types/react-router-config": { - "version": "5.0.11", - "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", - "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "^5.1.0" - } - }, - "node_modules/@types/react-router-dom": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "*" - } - }, - "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "license": "MIT" - }, - "node_modules/@types/sax": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", - "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/send": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", - "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "license": "MIT", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.8", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", - "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" - }, - "node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.33", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", - "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "license": "MIT" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "license": "ISC" - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.13.2", - "@webassemblyjs/helper-api-error": "1.13.2", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/wasm-gen": "1.14.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", - "license": "MIT", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", - "license": "Apache-2.0", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/helper-wasm-section": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-opt": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1", - "@webassemblyjs/wast-printer": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-api-error": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "license": "BSD-3-Clause" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "license": "Apache-2.0" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/accepts/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/accepts/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/accepts/node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/algoliasearch": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.27.0.tgz", - "integrity": "sha512-2PvAgvxxJzA3+dB+ERfS2JPdvUsxNf89Cc2GF5iCcFupTULOwmbfinvqrC4Qj9nHJJDNf494NqEN/1f9177ZTQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-abtesting": "5.27.0", - "@algolia/client-analytics": "5.27.0", - "@algolia/client-common": "5.27.0", - "@algolia/client-insights": "5.27.0", - "@algolia/client-personalization": "5.27.0", - "@algolia/client-query-suggestions": "5.27.0", - "@algolia/client-search": "5.27.0", - "@algolia/ingestion": "1.27.0", - "@algolia/monitoring": "1.27.0", - "@algolia/recommend": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/algoliasearch-helper": { - "version": "3.25.0", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.25.0.tgz", - "integrity": "sha512-vQoK43U6HXA9/euCqLjvyNdM4G2Fiu/VFp4ae0Gau9sZeIKBPvUPnXfLYAe65Bg7PFuw03coeu5K6lTPSXRObw==", - "license": "MIT", - "dependencies": { - "@algolia/events": "^4.0.1" - }, - "peerDependencies": { - "algoliasearch": ">= 3.1 < 6" - } - }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "license": "ISC", - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "engines": [ - "node >= 0.8.0" - ], - "license": "Apache-2.0", - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT" - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/astring": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", - "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", - "license": "MIT", - "bin": { - "astring": "bin/astring" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.21", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", - "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.24.4", - "caniuse-lite": "^1.0.30001702", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.1.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/babel-loader": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", - "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", - "license": "MIT", - "dependencies": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5" - } - }, - "node_modules/babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "license": "MIT", - "dependencies": { - "object.assign": "^4.1.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz", - "integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.4", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", - "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.3", - "core-js-compat": "^3.40.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz", - "integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==", - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.4" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "license": "MIT" - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7numerixpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/bonjour-service": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", - "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC" - }, - "node_modules/boxen": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", - "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", - "license": "MIT", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^6.2.0", - "chalk": "^4.1.2", - "cli-boxes": "^3.0.0", - "string-width": "^5.0.1", - "type-fest": "^2.5.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz", - "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001718", - "electron-to-chromium": "^1.5.160", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "license": "MIT" - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "license": "MIT", - "engines": { - "node": ">=14.16" - } - }, - "node_modules/cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", - "license": "MIT", - "dependencies": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "license": "MIT", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001723", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001723.tgz", - "integrity": "sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "license": "MIT", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "license": "MIT", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/clean-css": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", - "license": "MIT", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-table3": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", - "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/cli-table3/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/cli-table3/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/collapse-white-space": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "license": "MIT" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "license": "MIT" - }, - "node_modules/combine-promises": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", - "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "license": "ISC" - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "license": "MIT", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compressible/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz", - "integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "compressible": "~2.0.18", - "debug": "2.6.9", - "negotiator": "~0.6.4", - "on-headers": "~1.0.2", - "safe-buffer": "5.2.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7numerixpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "license": "MIT", - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "node_modules/config-chain/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" - }, - "node_modules/configstore": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", - "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", - "license": "BSD-2-Clause", - "dependencies": { - "dot-prop": "^6.0.1", - "graceful-fs": "^4.2.6", - "unique-string": "^3.0.0", - "write-file-atomic": "^3.0.3", - "xdg-basedir": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/yeoman/configstore?sponsor=1" - } - }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/consola": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", - "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, - "node_modules/content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "license": "MIT" - }, - "node_modules/copy-text-to-clipboard": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", - "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", - "license": "MIT", - "dependencies": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "license": "MIT", - "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/core-js": { - "version": "3.43.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.43.0.tgz", - "integrity": "sha512-N6wEbTTZSYOY2rYAn85CuvWWkCK6QweMn7/4Nr3w+gDBeBhk/x4EJeY6FPo4QzDoJZxVTv8U7CMvgWk6pOHHqA==", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat": { - "version": "3.43.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.43.0.tgz", - "integrity": "sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.25.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-pure": { - "version": "3.43.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.43.0.tgz", - "integrity": "sha512-i/AgxU2+A+BbJdMxh3v7/vxi2SbFqxiFmg6VsDwYB4jkucrd1BZNA9a9gphC0fYMG5IBSgQcbQnk865VCLe7xA==", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "license": "MIT" - }, - "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "license": "MIT", - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-random-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", - "license": "MIT", - "dependencies": { - "type-fest": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/crypto-random-string/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/css-blank-pseudo": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-7.0.1.tgz", - "integrity": "sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-blank-pseudo/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/css-declaration-sorter": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", - "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", - "license": "ISC", - "engines": { - "node": "^14 || ^16 || >=18" - }, - "peerDependencies": { - "postcss": "^8.0.9" - } - }, - "node_modules/css-has-pseudo": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-7.0.2.tgz", - "integrity": "sha512-nzol/h+E0bId46Kn2dQH5VElaknX2Sr0hFuB/1EomdC7j+OISt2ZzK7EHX9DZDY53WbIVAR7FYKSO2XnSf07MQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/selector-specificity": "^5.0.0", - "postcss-selector-parser": "^7.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-has-pseudo/node_modules/@csstools/selector-specificity": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" - } - }, - "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/css-loader": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", - "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", - "license": "MIT", - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.1.0", - "postcss-modules-local-by-default": "^4.0.5", - "postcss-modules-scope": "^3.2.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/css-minimizer-webpack-plugin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", - "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "cssnano": "^6.0.1", - "jest-worker": "^29.4.3", - "postcss": "^8.4.24", - "schema-utils": "^4.0.1", - "serialize-javascript": "^6.0.1" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@parcel/css": { - "optional": true - }, - "@swc/css": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "lightningcss": { - "optional": true - } - } - }, - "node_modules/css-prefers-color-scheme": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-10.0.0.tgz", - "integrity": "sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cssdb": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.3.0.tgz", - "integrity": "sha512-c7bmItIg38DgGjSwDPZOYF/2o0QU/sSgkWOMyl8votOfgFuyiFKWPesmCGEsrGLxEA9uL540cp8LdaGEjUGsZQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - } - ], - "license": "MIT-0" - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", - "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", - "license": "MIT", - "dependencies": { - "cssnano-preset-default": "^6.1.2", - "lilconfig": "^3.1.1" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-preset-advanced": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", - "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", - "license": "MIT", - "dependencies": { - "autoprefixer": "^10.4.19", - "browserslist": "^4.23.0", - "cssnano-preset-default": "^6.1.2", - "postcss-discard-unused": "^6.0.5", - "postcss-merge-idents": "^6.0.3", - "postcss-reduce-idents": "^6.0.3", - "postcss-zindex": "^6.0.2" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-preset-default": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", - "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "css-declaration-sorter": "^7.2.0", - "cssnano-utils": "^4.0.2", - "postcss-calc": "^9.0.1", - "postcss-colormin": "^6.1.0", - "postcss-convert-values": "^6.1.0", - "postcss-discard-comments": "^6.0.2", - "postcss-discard-duplicates": "^6.0.3", - "postcss-discard-empty": "^6.0.3", - "postcss-discard-overridden": "^6.0.2", - "postcss-merge-longhand": "^6.0.5", - "postcss-merge-rules": "^6.1.1", - "postcss-minify-font-values": "^6.1.0", - "postcss-minify-gradients": "^6.0.3", - "postcss-minify-params": "^6.1.0", - "postcss-minify-selectors": "^6.0.4", - "postcss-normalize-charset": "^6.0.2", - "postcss-normalize-display-values": "^6.0.2", - "postcss-normalize-positions": "^6.0.2", - "postcss-normalize-repeat-style": "^6.0.2", - "postcss-normalize-string": "^6.0.2", - "postcss-normalize-timing-functions": "^6.0.2", - "postcss-normalize-unicode": "^6.1.0", - "postcss-normalize-url": "^6.0.2", - "postcss-normalize-whitespace": "^6.0.2", - "postcss-ordered-values": "^6.0.2", - "postcss-reduce-initial": "^6.1.0", - "postcss-reduce-transforms": "^6.0.2", - "postcss-svgo": "^6.0.3", - "postcss-unique-selectors": "^6.0.4" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-utils": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", - "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "license": "MIT", - "dependencies": { - "css-tree": "~2.2.0" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "license": "CC0-1.0" - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT" - }, - "node_modules/debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", - "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "license": "BSD-2-Clause", - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "license": "MIT" - }, - "node_modules/detect-port": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz", - "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==", - "license": "MIT", - "dependencies": { - "address": "^1.0.1", - "debug": "4" - }, - "bin": { - "detect": "bin/detect-port.js", - "detect-port": "bin/detect-port.js" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "license": "MIT", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "license": "MIT", - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "license": "MIT", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dot-prop/node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "license": "MIT" - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "license": "MIT" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.167", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.167.tgz", - "integrity": "sha512-LxcRvnYO5ez2bMOFpbuuVuAI5QNeY1ncVytE/KXaL6ZNfzX1yPlAO0nSOyIHx2fVAuUprMqPs/TdVhUFZy7SIQ==", - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" - }, - "node_modules/emojilib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", - "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", - "license": "MIT" - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/emoticon": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.1.0.tgz", - "integrity": "sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", - "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "license": "MIT" - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esast-util-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", - "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/esast-util-from-js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", - "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "acorn": "^8.0.0", - "esast-util-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-goat": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", - "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-util-attach-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", - "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-build-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", - "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-walker": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-is-identifier-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-scope": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", - "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-to-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", - "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "astring": "^1.8.0", - "source-map": "^0.7.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-value-to-estree": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.4.0.tgz", - "integrity": "sha512-Zlp+gxis+gCfK12d3Srl2PdX2ybsEA8ZYy6vQGVQTNNYLEGRQQ56XB64bjemN8kxIKXP1nC9ip4Z+ILy9LGzvQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/remcohaszing" - } - }, - "node_modules/estree-util-visit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", - "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eta": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", - "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "url": "https://github.com/eta-dev/eta?sponsor=1" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eval": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", - "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", - "dependencies": { - "@types/node": "*", - "require-like": ">= 0.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "license": "MIT" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express/node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7numerixpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", - "license": "MIT" - }, - "node_modules/express/node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fault": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", - "license": "MIT", - "dependencies": { - "format": "^0.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "license": "Apache-2.0", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/feed": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", - "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", - "license": "MIT", - "dependencies": { - "xml-js": "^1.6.11" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "license": "MIT", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/file-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/file-loader/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/file-loader/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7numerixpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", - "license": "MIT", - "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "license": "MIT", - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", - "license": "MIT", - "engines": { - "node": ">= 14.17" - } - }, - "node_modules/format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/fs-monkey": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", - "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", - "license": "Unlicense" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", - "license": "ISC" - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/github-slugger": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", - "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==", - "license": "ISC" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "license": "BSD-2-Clause" - }, - "node_modules/global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "license": "MIT", - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/got/node_modules/@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/gray-matter": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", - "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", - "license": "MIT", - "dependencies": { - "js-yaml": "^3.13.1", - "kind-of": "^6.0.2", - "section-matter": "^1.0.0", - "strip-bom-string": "^1.0.0" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/gray-matter/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/gray-matter/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "license": "MIT", - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "license": "MIT" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-yarn": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", - "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", - "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^9.0.0", - "property-information": "^7.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", - "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-estree": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", - "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.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.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-js": "^1.0.0", - "unist-util-position": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", - "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-js": "^1.0.0", - "unist-util-position": "^5.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", - "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5/node_modules/property-information": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", - "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", - "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, - "node_modules/history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "license": "BSD-3-Clause", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "license": "MIT" - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/html-entities": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", - "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ], - "license": "MIT" - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "license": "MIT" - }, - "node_modules/html-minifier-terser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", - "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", - "license": "MIT", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "~5.3.2", - "commander": "^10.0.0", - "entities": "^4.4.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.15.1" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - } - }, - "node_modules/html-minifier-terser/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/html-webpack-plugin": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz", - "integrity": "sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==", - "license": "MIT", - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/html-webpack-plugin/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "license": "MIT", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", - "license": "BSD-2-Clause" - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "license": "MIT" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", - "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", - "license": "MIT" - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "license": "MIT", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", - "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", - "license": "MIT", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "license": "MIT", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/image-size": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz", - "integrity": "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==", - "license": "MIT", - "bin": { - "image-size": "bin/image-size.js" - }, - "engines": { - "node": ">=16.x" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/infima": { - "version": "0.2.0-alpha.45", - "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.45.tgz", - "integrity": "sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/inline-style-parser": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", - "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==", - "license": "MIT" - }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "license": "MIT", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "license": "MIT" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "license": "MIT", - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "license": "MIT", - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-npm": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", - "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "license": "MIT" - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-yarn-global": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", - "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jiti": { - "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "license": "MIT", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/joi": { - "version": "17.13.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", - "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.5", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "license": "MIT" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/latest-version": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", - "license": "MIT", - "dependencies": { - "package-json": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/launch-editor": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.10.0.tgz", - "integrity": "sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==", - "license": "MIT", - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/lilconfig": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "license": "MIT" - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "license": "MIT", - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "license": "MIT", - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "license": "MIT" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "license": "MIT" - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "license": "MIT" - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/markdown-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", - "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdown-table": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", - "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/mdast-util-directive": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", - "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", - "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", - "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/mdast-util-frontmatter": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", - "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "escape-string-regexp": "^5.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-gfm": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", - "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.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.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", - "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", - "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", - "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", - "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "license": "CC0-1.0" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "license": "Unlicense", - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-directive": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", - "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-frontmatter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", - "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", - "license": "MIT", - "dependencies": { - "fault": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "license": "MIT", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", - "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", - "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-mdx-expression": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", - "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-mdx-jsx": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", - "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-mdx-md": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", - "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", - "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", - "license": "MIT", - "dependencies": { - "acorn": "^8.0.0", - "acorn-jsx": "^5.0.0", - "micromark-extension-mdx-expression": "^3.0.0", - "micromark-extension-mdx-jsx": "^3.0.0", - "micromark-extension-mdx-md": "^2.0.0", - "micromark-extension-mdxjs-esm": "^3.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", - "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-factory-mdx-expression": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", - "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-factory-space/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-util-character/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-events-to-acorn": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", - "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "license": "MIT", - "dependencies": { - "mime-db": "~1.33.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", - "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", - "license": "MIT", - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "license": "ISC" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mrmime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "license": "MIT", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "license": "MIT" - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "license": "MIT", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-emoji": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", - "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^4.6.0", - "char-regex": "^1.0.2", - "emojilib": "^2.4.0", - "skin-tone": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.2.tgz", - "integrity": "sha512-Ee/R3SyN4BuynXcnTaekmaVdbDAEiNrHqjQIA37mHU8G9pf7aaAD4ZX3XjBLo6rsdcxA/gtkcNYZLt30ACgynw==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==", - "license": "MIT" - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/null-loader": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz", - "integrity": "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==", - "license": "MIT", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/null-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/null-loader/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/null-loader/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/null-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "license": "MIT" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "license": "MIT", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "license": "(WTFPL OR MIT)", - "bin": { - "opener": "bin/opener-bin.js" - } - }, - "node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "license": "MIT", - "engines": { - "node": ">=12.20" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "license": "MIT", - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-queue": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", - "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", - "license": "MIT", - "dependencies": { - "eventemitter3": "^4.0.4", - "p-timeout": "^3.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "license": "MIT", - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "license": "MIT", - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/package-json": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", - "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", - "license": "MIT", - "dependencies": { - "got": "^12.1.0", - "registry-auth-token": "^5.0.1", - "registry-url": "^6.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "license": "MIT", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-entities": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", - "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse-entities/node_modules/@types/unist": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", - "license": "MIT" - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse-numeric-range": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", - "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==", - "license": "ISC" - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", - "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.3", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5/node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "license": "(WTFPL OR MIT)" - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "license": "MIT" - }, - "node_modules/path-to-regexp": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", - "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", - "license": "MIT", - "dependencies": { - "isarray": "0.0.1" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", - "license": "MIT", - "dependencies": { - "find-up": "^6.3.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/postcss": { - "version": "8.5.5", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.5.tgz", - "integrity": "sha512-d/jtm+rdNT8tpXuHY5MMtcbJFBkhXE6593XVR9UoGCH8jSFGci7jGvMGH5RYd5PBJW+00NZQt6gf7CbagJCrhg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-attribute-case-insensitive": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-7.0.1.tgz", - "integrity": "sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-attribute-case-insensitive/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-calc": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", - "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.11", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.2" - } - }, - "node_modules/postcss-clamp": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", - "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=7.6.0" - }, - "peerDependencies": { - "postcss": "^8.4.6" - } - }, - "node_modules/postcss-color-functional-notation": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.10.tgz", - "integrity": "sha512-k9qX+aXHBiLTRrWoCJuUFI6F1iF6QJQUXNVWJVSbqZgj57jDhBlOvD8gNUGl35tgqDivbGLhZeW3Ongz4feuKA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-color-hex-alpha": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-10.0.0.tgz", - "integrity": "sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-color-rebeccapurple": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-10.0.0.tgz", - "integrity": "sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-colormin": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", - "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "colord": "^2.9.3", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-convert-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", - "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-custom-media": { - "version": "11.0.6", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-11.0.6.tgz", - "integrity": "sha512-C4lD4b7mUIw+RZhtY7qUbf4eADmb7Ey8BFA2px9jUbwg7pjTZDl4KY4bvlUV+/vXQvzQRfiGEVJyAbtOsCMInw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/cascade-layer-name-parser": "^2.0.5", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/media-query-list-parser": "^4.0.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-custom-properties": { - "version": "14.0.6", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-14.0.6.tgz", - "integrity": "sha512-fTYSp3xuk4BUeVhxCSJdIPhDLpJfNakZKoiTDx7yRGCdlZrSJR7mWKVOBS4sBF+5poPQFMj2YdXx1VHItBGihQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/cascade-layer-name-parser": "^2.0.5", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-custom-selectors": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-8.0.5.tgz", - "integrity": "sha512-9PGmckHQswiB2usSO6XMSswO2yFWVoCAuih1yl9FVcwkscLjRKjwsjM3t+NIWpSU2Jx3eOiK2+t4vVTQaoCHHg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/cascade-layer-name-parser": "^2.0.5", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-dir-pseudo-class": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-9.0.1.tgz", - "integrity": "sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-discard-comments": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", - "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", - "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-empty": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", - "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", - "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-unused": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", - "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-double-position-gradients": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.2.tgz", - "integrity": "sha512-7qTqnL7nfLRyJK/AHSVrrXOuvDDzettC+wGoienURV8v2svNbu6zJC52ruZtHaO6mfcagFmuTGFdzRsJKB3k5Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-focus-visible": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-10.0.1.tgz", - "integrity": "sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-focus-visible/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-focus-within": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-9.0.1.tgz", - "integrity": "sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-focus-within/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-font-variant": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", - "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", - "license": "MIT", - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-gap-properties": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-6.0.0.tgz", - "integrity": "sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-image-set-function": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-7.0.0.tgz", - "integrity": "sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxnumerixZ5Tv7eiDB9U87znA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-lab-function": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.10.tgz", - "integrity": "sha512-tqs6TCEv9tC1Riq6fOzHuHcZyhg4k3gIAMB8GGY/zA1ssGdm6puHMVE7t75aOSoFg7UD2wyrFFhbldiCMyyFTQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-loader": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", - "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", - "license": "MIT", - "dependencies": { - "cosmiconfig": "^8.3.5", - "jiti": "^1.20.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - } - }, - "node_modules/postcss-logical": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-8.1.0.tgz", - "integrity": "sha512-pL1hXFQ2fEXNKiNiAgtfA005T9FBxky5zkX6s4GZM2D8RkVgRqz3f4g1JUoq925zXv495qk8UNldDwh8uGEDoA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-merge-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", - "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", - "license": "MIT", - "dependencies": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-merge-longhand": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", - "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^6.1.1" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-merge-rules": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", - "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^4.0.2", - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", - "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", - "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", - "license": "MIT", - "dependencies": { - "colord": "^2.9.3", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-params": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", - "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", - "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", - "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", - "license": "MIT", - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^7.0.0", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", - "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", - "license": "ISC", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "license": "ISC", - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-nesting": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.2.tgz", - "integrity": "sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/selector-resolve-nested": "^3.1.0", - "@csstools/selector-specificity": "^5.0.0", - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-nesting/node_modules/@csstools/selector-resolve-nested": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.1.0.tgz", - "integrity": "sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" - } - }, - "node_modules/postcss-nesting/node_modules/@csstools/selector-specificity": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" - } - }, - "node_modules/postcss-nesting/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", - "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", - "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", - "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", - "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-string": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", - "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", - "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", - "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-url": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", - "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", - "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-opacity-percentage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-3.0.0.tgz", - "integrity": "sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==", - "funding": [ - { - "type": "kofi", - "url": "https://ko-fi.com/mrcgrtz" - }, - { - "type": "liberapay", - "url": "https://liberapay.com/mrcgrtz" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-ordered-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", - "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", - "license": "MIT", - "dependencies": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-overflow-shorthand": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-6.0.0.tgz", - "integrity": "sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-page-break": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", - "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", - "license": "MIT", - "peerDependencies": { - "postcss": "^8" - } - }, - "node_modules/postcss-place": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-10.0.0.tgz", - "integrity": "sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-preset-env": { - "version": "10.2.3", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.2.3.tgz", - "integrity": "sha512-zlQN1yYmA7lFeM1wzQI14z97mKoM8qGng+198w1+h6sCud/XxOjcKtApY9jWr7pXNS3yHDEafPlClSsWnkY8ow==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/postcss-cascade-layers": "^5.0.1", - "@csstools/postcss-color-function": "^4.0.10", - "@csstools/postcss-color-mix-function": "^3.0.10", - "@csstools/postcss-color-mix-variadic-function-arguments": "^1.0.0", - "@csstools/postcss-content-alt-text": "^2.0.6", - "@csstools/postcss-exponential-functions": "^2.0.9", - "@csstools/postcss-font-format-keywords": "^4.0.0", - "@csstools/postcss-gamut-mapping": "^2.0.10", - "@csstools/postcss-gradients-interpolation-method": "^5.0.10", - "@csstools/postcss-hwb-function": "^4.0.10", - "@csstools/postcss-ic-unit": "^4.0.2", - "@csstools/postcss-initial": "^2.0.1", - "@csstools/postcss-is-pseudo-class": "^5.0.3", - "@csstools/postcss-light-dark-function": "^2.0.9", - "@csstools/postcss-logical-float-and-clear": "^3.0.0", - "@csstools/postcss-logical-overflow": "^2.0.0", - "@csstools/postcss-logical-overscroll-behavior": "^2.0.0", - "@csstools/postcss-logical-resize": "^3.0.0", - "@csstools/postcss-logical-viewport-units": "^3.0.4", - "@csstools/postcss-media-minmax": "^2.0.9", - "@csstools/postcss-media-queries-aspect-ratio-number-values": "^3.0.5", - "@csstools/postcss-nested-calc": "^4.0.0", - "@csstools/postcss-normalize-display-values": "^4.0.0", - "@csstools/postcss-oklab-function": "^4.0.10", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/postcss-random-function": "^2.0.1", - "@csstools/postcss-relative-color-syntax": "^3.0.10", - "@csstools/postcss-scope-pseudo-class": "^4.0.1", - "@csstools/postcss-sign-functions": "^1.1.4", - "@csstools/postcss-stepped-value-functions": "^4.0.9", - "@csstools/postcss-text-decoration-shorthand": "^4.0.2", - "@csstools/postcss-trigonometric-functions": "^4.0.9", - "@csstools/postcss-unset-value": "^4.0.0", - "autoprefixer": "^10.4.21", - "browserslist": "^4.25.0", - "css-blank-pseudo": "^7.0.1", - "css-has-pseudo": "^7.0.2", - "css-prefers-color-scheme": "^10.0.0", - "cssdb": "^8.3.0", - "postcss-attribute-case-insensitive": "^7.0.1", - "postcss-clamp": "^4.1.0", - "postcss-color-functional-notation": "^7.0.10", - "postcss-color-hex-alpha": "^10.0.0", - "postcss-color-rebeccapurple": "^10.0.0", - "postcss-custom-media": "^11.0.6", - "postcss-custom-properties": "^14.0.6", - "postcss-custom-selectors": "^8.0.5", - "postcss-dir-pseudo-class": "^9.0.1", - "postcss-double-position-gradients": "^6.0.2", - "postcss-focus-visible": "^10.0.1", - "postcss-focus-within": "^9.0.1", - "postcss-font-variant": "^5.0.0", - "postcss-gap-properties": "^6.0.0", - "postcss-image-set-function": "^7.0.0", - "postcss-lab-function": "^7.0.10", - "postcss-logical": "^8.1.0", - "postcss-nesting": "^13.0.2", - "postcss-opacity-percentage": "^3.0.0", - "postcss-overflow-shorthand": "^6.0.0", - "postcss-page-break": "^3.0.4", - "postcss-place": "^10.0.0", - "postcss-pseudo-class-any-link": "^10.0.1", - "postcss-replace-overflow-wrap": "^4.0.0", - "postcss-selector-not": "^8.0.1" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-pseudo-class-any-link": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-10.0.1.tgz", - "integrity": "sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-reduce-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", - "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", - "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", - "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-replace-overflow-wrap": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", - "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", - "license": "MIT", - "peerDependencies": { - "postcss": "^8.0.3" - } - }, - "node_modules/postcss-selector-not": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-8.0.1.tgz", - "integrity": "sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-selector-not/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-sort-media-queries": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", - "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", - "license": "MIT", - "dependencies": { - "sort-css-media-queries": "2.2.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.4.23" - } - }, - "node_modules/postcss-svgo": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", - "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^3.2.0" - }, - "engines": { - "node": "^14 || ^16 || >= 18" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", - "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "license": "MIT" - }, - "node_modules/postcss-zindex": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", - "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "license": "MIT", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "node_modules/pretty-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/prism-react-renderer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.1.tgz", - "integrity": "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==", - "license": "MIT", - "dependencies": { - "@types/prismjs": "^1.26.0", - "clsx": "^2.0.0" - }, - "peerDependencies": { - "react": ">=16.0.0" - } - }, - "node_modules/prismjs": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", - "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "license": "MIT" - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "license": "ISC" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pupa": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", - "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", - "license": "MIT", - "dependencies": { - "escape-goat": "^4.0.0" - }, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", - "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", - "license": "MIT", - "dependencies": { - "scheduler": "^0.26.0" - }, - "peerDependencies": { - "react": "^19.1.0" - } - }, - "node_modules/react-fast-compare": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", - "license": "MIT" - }, - "node_modules/react-helmet-async": { - "name": "@slorber/react-helmet-async", - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@slorber/react-helmet-async/-/react-helmet-async-1.3.0.tgz", - "integrity": "sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.12.5", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.2.0", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" - }, - "node_modules/react-json-view-lite": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-2.4.1.tgz", - "integrity": "sha512-fwFYknRIBxjbFm0kBDrzgBy1xa5tDg2LyXXBepC5f1b+MY3BUClMCsvanMPn089JbV1Eg3nZcrp0VCuH43aXnA==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/react-loadable": { - "name": "@docusaurus/react-loadable", - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", - "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", - "license": "MIT", - "dependencies": { - "@types/react": "*" - }, - "peerDependencies": { - "react": "*" - } - }, - "node_modules/react-loadable-ssr-addon-v5-slorber": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", - "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.10.3" - }, - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "react-loadable": "*", - "webpack": ">=4.41.1 || 5.x" - } - }, - "node_modules/react-router": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/react-router-config": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", - "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.1.2" - }, - "peerDependencies": { - "react": ">=15", - "react-router": ">=5" - } - }, - "node_modules/react-router-dom": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.3.4", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/recma-build-jsx": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", - "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-util-build-jsx": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/recma-jsx": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.0.tgz", - "integrity": "sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==", - "license": "MIT", - "dependencies": { - "acorn-jsx": "^5.0.0", - "estree-util-to-js": "^2.0.0", - "recma-parse": "^1.0.0", - "recma-stringify": "^1.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/recma-parse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", - "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "esast-util-from-js": "^2.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/recma-stringify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", - "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-util-to-js": "^2.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "license": "MIT" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", - "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", - "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regexpu-core": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", - "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", - "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.2.0", - "regjsgen": "^0.8.0", - "regjsparser": "^0.12.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/registry-auth-token": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.0.tgz", - "integrity": "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==", - "license": "MIT", - "dependencies": { - "@pnpm/npm-conf": "^2.1.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/registry-url": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", - "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", - "license": "MIT", - "dependencies": { - "rc": "1.2.8" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", - "license": "MIT" - }, - "node_modules/regjsparser": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", - "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", - "license": "BSD-2-Clause", - "dependencies": { - "jsesc": "~3.0.2" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-recma": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", - "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "hast-util-to-estree": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remark-directive": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.1.tgz", - "integrity": "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-directive": "^3.0.0", - "micromark-extension-directive": "^3.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-emoji": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", - "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.2", - "emoticon": "^4.0.1", - "mdast-util-find-and-replace": "^3.0.1", - "node-emoji": "^2.1.0", - "unified": "^11.0.4" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/remark-frontmatter": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", - "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-frontmatter": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", - "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-mdx": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.0.tgz", - "integrity": "sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==", - "license": "MIT", - "dependencies": { - "mdast-util-mdx": "^3.0.0", - "micromark-extension-mdxjs": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", - "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "license": "MIT", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "node_modules/renderkid/node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/renderkid/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-like": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", - "engines": { - "node": "*" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "license": "MIT" - }, - "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "license": "MIT" - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", - "license": "MIT" - }, - "node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "license": "MIT", - "dependencies": { - "lowercase-keys": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rtlcss": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", - "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", - "license": "MIT", - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0", - "postcss": "^8.4.21", - "strip-json-comments": "^3.1.1" - }, - "bin": { - "rtlcss": "bin/rtlcss.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", - "license": "ISC" - }, - "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", - "license": "MIT" - }, - "node_modules/schema-dts": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/schema-dts/-/schema-dts-1.1.5.tgz", - "integrity": "sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg==", - "license": "Apache-2.0" - }, - "node_modules/schema-utils": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", - "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/search-insights": { - "version": "2.17.3", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", - "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", - "license": "MIT", - "peer": true - }, - "node_modules/section-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "license": "MIT" - }, - "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "license": "MIT", - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", - "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7numerixpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-handler": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", - "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", - "license": "MIT", - "dependencies": { - "bytes": "3.0.0", - "content-disposition": "0.5.2", - "mime-types": "2.1.18", - "minimatch": "3.1.2", - "path-is-inside": "1.0.2", - "path-to-regexp": "3.3.0", - "range-parser": "1.2.0" - } - }, - "node_modules/serve-handler/node_modules/path-to-regexp": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", - "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", - "license": "MIT" - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "license": "MIT", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "license": "ISC" - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7numerixpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "license": "ISC" - }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "license": "MIT", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", - "license": "MIT" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" - }, - "node_modules/sirv": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", - "license": "MIT", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "license": "MIT" - }, - "node_modules/sitemap": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", - "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", - "license": "MIT", - "dependencies": { - "@types/node": "^17.0.5", - "@types/sax": "^1.2.1", - "arg": "^5.0.0", - "sax": "^1.2.4" - }, - "bin": { - "sitemap": "dist/cli.js" - }, - "engines": { - "node": ">=12.0.0", - "npm": ">=5.6.0" - } - }, - "node_modules/sitemap/node_modules/@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", - "license": "MIT" - }, - "node_modules/skin-tone": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", - "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", - "license": "MIT", - "dependencies": { - "unicode-emoji-modifier-base": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/snake-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "license": "MIT", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "license": "MIT", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/sort-css-media-queries": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", - "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", - "license": "MIT", - "engines": { - "node": ">= 6.3.0" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "license": "BSD-3-Clause" - }, - "node_modules/srcset": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", - "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/std-env": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", - "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", - "license": "MIT" - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "license": "MIT", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "license": "BSD-2-Clause", - "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/style-to-js": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz", - "integrity": "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==", - "license": "MIT", - "dependencies": { - "style-to-object": "1.0.8" - } - }, - "node_modules/style-to-object": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", - "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", - "license": "MIT", - "dependencies": { - "inline-style-parser": "0.2.4" - } - }, - "node_modules/stylehacks": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", - "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", - "license": "MIT" - }, - "node_modules/svgo": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", - "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", - "license": "MIT", - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^5.1.0", - "css-tree": "^2.3.1", - "css-what": "^6.1.0", - "csso": "^5.0.5", - "picocolors": "^1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/svgo" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/tapable": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", - "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.42.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.42.0.tgz", - "integrity": "sha512-UYCvU9YQW2f/Vwl+P0GfhxJxbUGLwd+5QrrGgLajzWAtC/23AX0vcise32kkP7Eu0Wu9VlzzHAXkLObgjQfFlQ==", - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.14.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.14", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", - "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "serialize-javascript": "^6.0.2", - "terser": "^5.31.1" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "license": "MIT" - }, - "node_modules/tiny-invariant": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", - "license": "MIT" - }, - "node_modules/tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", - "license": "MIT" - }, - "node_modules/tinypool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.0.tgz", - "integrity": "sha512-7CotroY9a8DKsKprEy/a14aCCm8jYVmR7aFy4fpkZM8sdpNJbKkixuNjgM50yCmip2ezc8z4N7k3oe2+rfRJCQ==", - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/type-is/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/type-is/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "license": "MIT", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/undici-types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", - "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", - "license": "MIT" - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", - "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-emoji-modifier-base": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", - "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "license": "MIT", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", - "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unified": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unique-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", - "license": "MIT", - "dependencies": { - "crypto-random-string": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", - "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/update-notifier": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", - "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", - "license": "BSD-2-Clause", - "dependencies": { - "boxen": "^7.0.0", - "chalk": "^5.0.1", - "configstore": "^6.0.0", - "has-yarn": "^3.0.0", - "import-lazy": "^4.0.0", - "is-ci": "^3.0.1", - "is-installed-globally": "^0.4.0", - "is-npm": "^6.0.0", - "is-yarn-global": "^0.4.0", - "latest-version": "^7.0.0", - "pupa": "^3.1.0", - "semver": "^7.3.7", - "semver-diff": "^4.0.0", - "xdg-basedir": "^5.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/yeoman/update-notifier?sponsor=1" - } - }, - "node_modules/update-notifier/node_modules/boxen": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", - "license": "MIT", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/update-notifier/node_modules/camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/update-notifier/node_modules/chalk": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", - "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "license": "MIT", - "dependencies": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "file-loader": "*", - "webpack": "^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "file-loader": { - "optional": true - } - } - }, - "node_modules/url-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/url-loader/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/url-loader/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/url-loader/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/url-loader/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/url-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", - "license": "MIT" - }, - "node_modules/utility-types": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", - "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", - "license": "MIT" - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", - "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/watchpack": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", - "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", - "license": "MIT", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "license": "MIT", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/webpack": { - "version": "5.99.9", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz", - "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", - "license": "MIT", - "dependencies": { - "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.14.0", - "browserslist": "^4.24.0", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^4.3.2", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-bundle-analyzer": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", - "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "0.5.7", - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "commander": "^7.2.0", - "debounce": "^1.2.1", - "escape-string-regexp": "^4.0.0", - "gzip-size": "^6.0.0", - "html-escaper": "^2.0.2", - "opener": "^1.5.2", - "picocolors": "^1.0.0", - "sirv": "^2.0.3", - "ws": "^7.3.1" - }, - "bin": { - "webpack-bundle-analyzer": "lib/bin/analyzer.js" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "license": "MIT", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-dev-middleware/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack-dev-middleware/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack-dev-middleware/node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack-dev-server": { - "version": "4.15.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", - "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", - "license": "MIT", - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.4", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.18.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", - "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/webpack-merge": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", - "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", - "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.2.tgz", - "integrity": "sha512-ykKKus8lqlgXX/1WjudpIEjqsafjOTcOJqxnAbMLAu/KCsDCJ6GBtvscewvTkrn24HsnvFwrSCbenFrhtcCsAA==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpackbar": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-6.0.1.tgz", - "integrity": "sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==", - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", - "consola": "^3.2.3", - "figures": "^3.2.0", - "markdown-table": "^2.0.0", - "pretty-time": "^1.1.0", - "std-env": "^3.7.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=14.21.3" - }, - "peerDependencies": { - "webpack": "3 || 4 || 5" - } - }, - "node_modules/webpackbar/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/webpackbar/node_modules/markdown-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", - "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", - "license": "MIT", - "dependencies": { - "repeat-string": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/webpackbar/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/webpackbar/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "license": "Apache-2.0", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "license": "MIT", - "dependencies": { - "string-width": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "license": "MIT" - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xdg-basedir": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", - "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/xml-js": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", - "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", - "license": "MIT", - "dependencies": { - "sax": "^1.2.4" - }, - "bin": { - "xml-js": "bin/cli.js" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "license": "ISC" - }, - "node_modules/yocto-queue": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz", - "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==", - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/docs-src/src/pages/index.js b/docs-src/src/pages/index.js index d2d965fd..c58e5f55 100644 --- a/docs-src/src/pages/index.js +++ b/docs-src/src/pages/index.js @@ -167,6 +167,43 @@ function SDKsAbout() { ); } +function NumerixAbout() { + return ( +
+
+
+
+ Numerix +

+ Numerix is a mathematical compute engine for BharatML Stack. It is used to perform mathematical operations on matrices and vectors. +

+ + Explore Numerix → + +
+
+
+

🛠️ Numerix Features

+
    +
  • ✅ Postfix expression evaluation
  • +
  • ✅ Vectorized math operations
  • +
  • ✅ Typed evaluation
  • +
  • ✅ Compiler-assisted SIMD
  • +
  • ✅ ARM & AMD support
  • +
  • ✅ Multi-arch builds
  • +
  • ✅ Deterministic runtime
  • + +
+
+
+
+
+
+ ); +} + export default function Home() { const {siteConfig} = useDocusaurusContext(); return ( @@ -181,6 +218,7 @@ export default function Home() { + ); diff --git a/docs-src/static/img/v1.0.0-inferflow-arch.png b/docs-src/static/img/v1.0.0-inferflow-arch.png new file mode 100644 index 00000000..acad4888 Binary files /dev/null and b/docs-src/static/img/v1.0.0-inferflow-arch.png differ diff --git a/docs-src/static/img/v1.0.0-inferflow-dag-matrix.png b/docs-src/static/img/v1.0.0-inferflow-dag-matrix.png new file mode 100644 index 00000000..2345d69f Binary files /dev/null and b/docs-src/static/img/v1.0.0-inferflow-dag-matrix.png differ diff --git a/docs-src/yarn.lock b/docs-src/yarn.lock index a0cac9b6..c1e7229f 100644 --- a/docs-src/yarn.lock +++ b/docs-src/yarn.lock @@ -6185,7 +6185,7 @@ mrmime@^2.0.0: ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7numerixpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== ms@2.1.3, ms@^2.1.3: version "2.1.3" @@ -6729,7 +6729,7 @@ postcss-gap-properties@^6.0.0: postcss-image-set-function@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-7.0.0.tgz#538e94e16716be47f9df0573b56bbaca86e1da53" - integrity sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxnumerixZ5Tv7eiDB9U87znA== + integrity sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA== dependencies: "@csstools/utilities" "^2.0.0" postcss-value-parser "^4.2.0" diff --git a/docs/404.html b/docs/404.html index 4d1bd7ff..a131da18 100644 --- a/docs/404.html +++ b/docs/404.html @@ -4,14 +4,14 @@ BharatMLStack - - - + + + -

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

+

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

\ No newline at end of file diff --git a/docs/assets/css/styles.8dc7ce64.css b/docs/assets/css/styles.14b2d0af.css similarity index 92% rename from docs/assets/css/styles.8dc7ce64.css rename to docs/assets/css/styles.14b2d0af.css index 088734c6..8bc1333c 100644 --- a/docs/assets/css/styles.8dc7ce64.css +++ b/docs/assets/css/styles.14b2d0af.css @@ -1 +1 @@ -@layer docusaurus.infima,docusaurus.theme-common,docusaurus.theme-classic,docusaurus.core,docusaurus.plugin-debug,docusaurus.theme-mermaid,docusaurus.theme-live-codeblock,docusaurus.theme-search-algolia.docsearch,docusaurus.theme-search-algolia;@layer docusaurus.infima{.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:#0000;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:#0000000d;--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 #0000001a;--ifm-global-shadow-md:0 5px 40px #0003;--ifm-global-shadow-tl:0 12px 28px 0 #0003,0 2px 4px 0 #0000001a;--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:#0000;--ifm-table-stripe-background:#00000008;--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:#0000}*{box-sizing:border-box}html{background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);-webkit-font-smoothing:antialiased;-webkit-tap-highlight-color:transparent;text-rendering:optimizelegibility;-webkit-text-size-adjust:100%;text-size-adjust:100%}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid #0000001a;border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:initial;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;display:block;margin-bottom:var(--ifm-spacing-vertical)}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){-webkit-text-decoration:none;text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom)}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.text--primary{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.alert__heading,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{list-style:none;padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:#3578e526;--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:#ebedf026;--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:#00a40026;--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:#54c7ec26;--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:#ffba0026;--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:#fa383e26;--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:any-link:hover,.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);-webkit-text-decoration:none;text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;-webkit-user-select:none;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:#0000;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.dropdown__link--active,.dropdown__link:hover,.menu__link:hover,.navbar__brand:hover,.navbar__link--active,.navbar__link:hover,.pagination-nav__link:hover,.pagination__link:hover{-webkit-text-decoration:none;text-decoration:none}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);-webkit-text-decoration:none;text-decoration:none}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}.dropdown__menu,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;list-style:none;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color)}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor #0000;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.footer__item{margin-top:0}.footer__items{margin-bottom:0}[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{list-style:none;margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color)}.menu__caret:before,.menu__link--sublist-caret:after{content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;left:0;opacity:0;position:fixed;top:0;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;visibility:hidden}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color)}.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color)}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:#ffffff1a;--ifm-navbar-search-input-placeholder-color:#ffffff80;color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:#ffffff0d;--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:1rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:#0009;right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav{display:grid;grid-gap:var(--ifm-spacing-horizontal);gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover)}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto;padding-left:0}.tabs__item{border-bottom:3px solid #0000;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:#ffffff0d;--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:#ffffff1a;--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:#ffffff12;--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec}}.bharatml-hero .bharatml-button:hover,.bharatml-hero .button--outline:hover,[data-theme=dark] .bharatml-hero .bharatml-button:hover,[data-theme=dark] .bharatml-hero .button--outline:hover{background-color:#fff!important;border-color:#fff!important;color:var(--bharatml-primary)!important}.bharatml-hero .bharatml-button,.bharatml-hero .button--outline{border:2px solid #fff!important;color:#fff!important;transition:.3s}:root{--ifm-color-primary:#450839;--ifm-color-primary-dark:#3d0732;--ifm-color-primary-darker:#39062f;--ifm-color-primary-darkest:#2f0527;--ifm-color-primary-light:#4d0940;--ifm-color-primary-lighter:#510a43;--ifm-color-primary-lightest:#5d0c4d;--ifm-code-font-size:95%;--docusaurus-highlighted-code-line-bg:#0000001a;--bharatml-primary:#450839;--bharatml-primary-hover:#6a0c59;--bharatml-secondary:#f9f9f9;--bharatml-text:#1c1e21;--bharatml-text-light:#606770}[data-theme=dark]{--ifm-color-primary:#8b4582;--ifm-color-primary-dark:#7d3f75;--ifm-color-primary-darker:#763c6e;--ifm-color-primary-darkest:#62315a;--ifm-color-primary-light:#994b8f;--ifm-color-primary-lighter:#a04e96;--ifm-color-primary-lightest:#b657a9;--docusaurus-highlighted-code-line-bg:#0000004d;--bharatml-primary:#8b4582;--bharatml-primary-hover:#a04e96;--bharatml-secondary:#1e1e1e;--bharatml-text:#e3e3e3;--bharatml-text-light:#b4b4b4}.bharatml-hero{background:linear-gradient(135deg,var(--bharatml-primary) 0,var(--bharatml-primary-hover) 100%);color:#fff}.bharatml-hero .bharatml-button{background-color:var(--bharatml-primary)}.bharatml-hero .button--outline{background-color:initial!important}[data-theme=dark] .bharatml-hero .bharatml-button{background-color:var(--bharatml-primary);border:2px solid #fff!important;color:#fff!important}[data-theme=dark] .bharatml-hero .button--outline{background-color:initial!important;border:2px solid #fff!important;color:#fff!important}.bharatml-button{background-color:var(--bharatml-primary);border-color:var(--bharatml-primary);transition:.3s}.bharatml-button:hover{background-color:var(--bharatml-primary-hover);border-color:var(--bharatml-primary-hover);color:#fff}.bharatml-card{background:#fff;border:1px solid #4508391a;border-radius:8px;padding:2rem;transition:.3s}.bharatml-card:hover{border-color:var(--bharatml-primary);box-shadow:0 4px 20px #4508391a;transform:translateY(-2px)}.bharatml-icon{align-items:center;background:linear-gradient(135deg,var(--bharatml-primary),var(--bharatml-primary-hover));border-radius:12px;color:#fff;display:flex;font-size:1.5rem;height:64px;justify-content:center;margin:0 auto 1rem;width:64px}@layer docusaurus.core{#__docusaurus-base-url-issue-banner-container{display:none}}.aboutSection_udvw,.features_t9lD{background-color:var(--ifm-background-surface-color)}.featuresHeader_qR2i,.features_t9lD h3{color:var(--bharatml-primary);margin-bottom:1rem}.features_t9lD{display:block;padding:4rem 0;text-align:center;width:100%}.featureSvg_GfXr{height:200px;width:200px}.featuresHeader_qR2i{font-size:2.5rem;font-weight:700;text-align:center}.featuresSubtitle_VdGe{color:var(--ifm-font-color-base);font-size:1.2rem;opacity:1;text-align:center}.features_t9lD .bharatml-card_xZ6l{height:100%;margin-top:1rem}.features_t9lD .bharatml-icon_XBoJ{margin-bottom:1.5rem}.features_t9lD h3{font-size:1.25rem;font-weight:600}.features_t9lD p{color:var(--ifm-font-color-base)!important;font-size:.95rem;font-weight:400;line-height:1.6;margin:0}.featureDescription_sP1D{color:#1c1e21!important;font-size:.95rem!important;font-weight:400!important;line-height:1.6!important;margin:0!important}[data-theme=dark] .bharatml-card_xZ6l{background:#2a2a2a!important;border-color:#8b45824d;color:#fff}[data-theme=dark] .bharatml-card_xZ6l:hover{background:#333!important;border-color:var(--bharatml-primary);box-shadow:0 4px 20px #8b45824d}[data-theme=dark] .featureDescription_sP1D,[data-theme=dark] .featuresHeader_qR2i,[data-theme=dark] .features_t9lD h3,[data-theme=dark] .features_t9lD p{color:#a04e96!important}[data-theme=dark] .featuresSubtitle_VdGe{color:#e0e0e0!important}.heroBanner_qdFl{overflow:hidden;padding:4rem 0;position:relative;text-align:center}.logoContainer_xdaK{align-items:center;display:flex;justify-content:center;margin-bottom:2rem}.heroLogo_U6bI{filter:drop-shadow(0 4px 8px rgba(0,0,0,.1));height:180px;transition:transform .3s;width:180px}.heroLogo_U6bI:hover{transform:scale(1.05)}.buttons_AeoN{align-items:center;gap:1rem;margin-bottom:2rem}.buttons_AeoN,.statsContainer_KpvY{display:flex;justify-content:center}.statsContainer_KpvY{gap:3rem;margin-top:2rem;opacity:.9}.statItem_bwiZ{align-items:center;color:#fff;display:flex;flex-direction:column;text-align:center}.statItem_bwiZ strong{display:block;font-size:1.5rem;font-weight:700;margin-bottom:.25rem}.statItem_bwiZ span{font-size:.875rem;letter-spacing:.5px;opacity:.8;text-transform:uppercase}.aboutSection_udvw{padding:4rem 0}.highlightBox_Uhe8{background:linear-gradient(135deg,#f8f9ff,#e8f0ff);border:1px solid #4508391a;border-radius:12px;height:100%;padding:2rem}.highlightBox_Uhe8 h3{color:var(--bharatml-primary);font-size:1.25rem;margin-bottom:1rem}.highlightBox_Uhe8 li,[data-theme=dark] .highlightBox_Uhe8 li{color:var(--bharatml-text)}.highlightBox_Uhe8 ul{list-style:none;margin:0;padding:0}.highlightBox_Uhe8 li{font-size:.95rem;padding:.5rem 0}.highlightBox_Uhe8 li:not(:last-child){border-bottom:1px solid #4508390d}[data-theme=dark] .highlightBox_Uhe8{background:linear-gradient(135deg,#1a1a2e,#16213e);border-color:#8b458233}@layer docusaurus.theme-common{.themedComponent_mlkZ{display:none}[data-theme=dark] .themedComponent--dark_xIcU,[data-theme=light] .themedComponent--light_NVdE,html:not([data-theme]) .themedComponent--light_NVdE{display:initial}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.errorBoundaryFallback_VBag{color:red;padding:.55rem}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;list-style:none;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:#0000 #0000 #0000 var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before{transform:rotate(90deg)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.collapsibleContent_i85q p:last-child,.details_lb9f>summary>p:last-child{margin-bottom:0}}@layer docusaurus.theme-classic{:root{--docusaurus-progress-bar-color:var(--ifm-color-primary);--docusaurus-announcement-bar-height:auto;--docusaurus-collapse-button-bg:#0000;--docusaurus-collapse-button-bg-hover:#0000001a;--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px;--docusaurus-blog-social-icon-size:1rem;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300)}#nprogress{pointer-events:none}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;left:0;position:fixed;top:0;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit;-webkit-text-decoration:underline;text-decoration:underline}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}.docSidebarContainer_YfHR,.navbarSearchContainer_Bca1:empty,.sidebarLogo_isFc,.toggleIcon_g3eP,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.announcementBarContent_xLdY{flex:1 1 auto}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{-webkit-tap-highlight-color:transparent;align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}[data-theme-choice=dark] .darkToggleIcon_wfgR,[data-theme-choice=light] .lightToggleIcon_pyhR,[data-theme-choice=system] .systemToggleIcon_QzmC{display:initial}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}[data-theme=dark]:root{--docusaurus-collapse-button-bg:#ffffff0d;--docusaurus-collapse-button-bg-hover:#ffffff1a}.collapseSidebarButton_PEFL{display:none;margin:0}.iconExternalLink_nPIU{margin-left:.3rem}.menuExternalLink_NmtK{align-items:center}.docMainContainer_TBSr,.docRoot_UBD9{display:flex;width:100%}.docsWrapper_hBAB{display:flex;flex:1 0 auto}.dropdownNavbarItemMobile_J0Sd{cursor:pointer}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.navbar__items--right>:last-child{padding-right:0}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.authorSocialIcon_XYv3,.authorSocialLink_owbf{width:var(--docusaurus-blog-social-icon-size)}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);-webkit-user-select:none;user-select:none}.hash-link:before{content:"#"}.docCardListItem_W1sv>*,body,html{height:100%}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.sidebar_re4s{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 2rem)}.authorSocials_rSDt,.authorTitle_nd0D{overflow:hidden;-webkit-box-orient:vertical}.sidebarItemTitle_pO2u{font-size:var(--ifm-h3-font-size);font-weight:var(--ifm-font-weight-bold)}.container_mt6G,.sidebarItemList_Yudw{font-size:.9rem}.sidebarItem__DBe{margin-top:.7rem}.sidebarItemLink_mo7H{color:var(--ifm-font-color-base);display:block}.sidebarItemLink_mo7H:hover{-webkit-text-decoration:none;text-decoration:none}.sidebarItemLinkActive_I1ZP{color:var(--ifm-color-primary)!important}.yearGroupHeading_rMGB{margin-bottom:.4rem;margin-top:1.6rem}.yearGroupHeading_QT03{margin:1rem .75rem .5rem}.cardContainer_fWXF{--ifm-link-color:var(--ifm-color-emphasis-800);--ifm-link-hover-color:var(--ifm-color-emphasis-700);--ifm-link-hover-decoration:none;border:1px solid var(--ifm-color-emphasis-200);box-shadow:0 1.5px 3px 0 #00000026;transition:all var(--ifm-transition-fast) ease;transition-property:border,box-shadow}.cardContainer_fWXF:hover{border-color:var(--ifm-color-primary);box-shadow:0 3px 6px 0 #0003}.admonitionContent_BuS1>:last-child,.cardContainer_fWXF :last-child{margin-bottom:0}.cardTitle_rnsV{font-size:1.2rem}.cardDescription_PWke{font-size:.8rem}.docCardListItem_W1sv{margin-bottom:2rem}.title_f1Hy{font-size:3rem}[data-theme=dark] .githubSvg_Uu4N,[data-theme=dark] .instagramSvg_YC40,[data-theme=dark] .threadsSvg_PTXY,[data-theme=dark] .xSvg_y3PF{fill:var(--light)}[data-theme=light] .githubSvg_Uu4N,[data-theme=light] .instagramSvg_YC40,[data-theme=light] .threadsSvg_PTXY,[data-theme=light] .xSvg_y3PF{fill:var(--dark)}.authorSocials_rSDt{align-items:center;display:flex;flex-wrap:wrap;line-clamp:1;-webkit-line-clamp:1}.authorSocialLink_owbf,.authorSocials_rSDt{height:var(--docusaurus-blog-social-icon-size);line-height:0}.authorSocialLink_owbf{margin-right:.4rem}.authorSocialIcon_XYv3{height:var(--docusaurus-blog-social-icon-size)}.authorImage_XqGP{--ifm-avatar-photo-size:3.6rem}.author-as-h1_n9oJ .authorImage_XqGP{--ifm-avatar-photo-size:7rem}.author-as-h2_gXvM .authorImage_XqGP{--ifm-avatar-photo-size:5.4rem}.authorDetails_lV9A{align-items:flex-start;display:flex;flex-direction:column;justify-content:space-around}.authorName_yefp{display:flex;flex-direction:row;font-size:1.1rem;line-height:1.1rem}.author-as-h1_n9oJ .authorName_yefp{display:inline;font-size:2.4rem;line-height:2.4rem}.author-as-h2_gXvM .authorName_yefp{display:inline;font-size:1.4rem;line-height:1.4rem}.authorTitle_nd0D{display:-webkit-box;font-size:.8rem;line-height:1rem;line-clamp:1;-webkit-line-clamp:1}.author-as-h1_n9oJ .authorTitle_nd0D{font-size:1.2rem;line-height:1.6rem}.author-as-h2_gXvM .authorTitle_nd0D{font-size:1rem;line-height:1.3rem}.authorBlogPostCount_iiJ5{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.8rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.authorListItem_n3yI{list-style-type:none;margin-bottom:2rem}.authorCol_Hf19{max-width:inherit!important}.imageOnlyAuthorRow_pa_O{display:flex;flex-flow:row wrap}.imageOnlyAuthorCol_G86a{margin-left:.3rem;margin-right:.3rem}.codeBlockContainer_Ckt0{background:var(--prism-background-color);border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);color:var(--prism-color);margin-bottom:var(--ifm-leading)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockStandalone_MEMb{padding:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.theme-code-block:hover .copyButtonCopied_Vdqa{opacity:1!important}.copyButtonIcons_IEyt{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_TrPX,.copyButtonSuccessIcon_cVMy{left:0;position:absolute;top:0;fill:currentColor;height:inherit;opacity:inherit;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_cVMy{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_Vdqa .copyButtonIcon_TrPX{opacity:0;transform:scale(.33)}.copyButtonCopied_Vdqa .copyButtonSuccessIcon_cVMy{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.wordWrapButtonIcon_b1P5{height:1.2rem;width:1.2rem}.wordWrapButtonEnabled_uzNF .wordWrapButtonIcon_b1P5{color:var(--ifm-color-primary)}.buttonGroup_M5ko{column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup_M5ko button{align-items:center;background:var(--prism-background-color);border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);color:var(--prism-color);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup_M5ko button:focus-visible,.buttonGroup_M5ko button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup_M5ko button{opacity:.4}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);-webkit-text-decoration:none;text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tag_Nnez{display:inline-block;margin:.5rem .5rem 0 1rem}.codeBlockContent_QJqH{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_OeMC{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlockTitle_OeMC+.codeBlockContent_QJqH .codeBlock_a8dz{border-top-left-radius:0;border-top-right-radius:0}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}.lastUpdated_JAkA{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.tocCollapsibleContent_vkbj a{display:block}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.containsTaskList_mC6p{list-style:none}:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.img_ev3q{height:auto}.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.admonition_xJq3{margin-bottom:1em}.admonitionHeading_Gvgb{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);text-transform:uppercase}.admonitionHeading_Gvgb:not(:last-child){margin-bottom:.3rem}.admonitionHeading_Gvgb code{text-transform:none}.admonitionIcon_Rf37{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_Rf37 svg{display:inline-block;height:1.6em;width:1.6em;fill:var(--ifm-alert-foreground-color)}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}.title_kItE{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-leading)*1.25)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*{margin-top:0}.mdxPageWrapper_j9I6{justify-content:center}}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_TmdG{background-color:var(--docusaurus-collapse-button-bg)}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_i1dp,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_TmdG:focus,.expandButton_TmdG:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);-webkit-text-decoration:none!important;text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_TmdG{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_i1dp{transform:rotate(180deg)}.docSidebarContainer_YfHR{border-right:1px solid var(--ifm-toc-border-color);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_DPk8{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_aRkj{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_TBSr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_lQrH{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_JWYK{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}.navbarSearchContainer_Bca1{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.lastUpdated_JAkA{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn,.generatedIndexPage_vN6x{max-width:75%!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.sidebar_re4s,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block;width:max-content}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.navbarSearchContainer_Bca1{position:absolute;right:var(--ifm-navbar-padding-horizontal)}.docItemContainer_F8PC{padding:0 .3rem}}@media screen and (max-width:996px){.features_t9lD .bharatml-card_xZ6l{margin-bottom:2rem}.featuresHeader_qR2i{font-size:2rem}.featuresSubtitle_VdGe{font-size:1rem}.heroBanner_qdFl{padding:2rem}}@media screen and (max-width:768px){.heroLogo_U6bI{height:120px;width:120px}.logoContainer_xdaK{margin-bottom:1.5rem}.buttons_AeoN{flex-direction:column;gap:.5rem}.statsContainer_KpvY{align-items:center;flex-direction:column;gap:1rem}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}.title_f1Hy{font-size:2rem}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file +@layer docusaurus.infima,docusaurus.theme-common,docusaurus.theme-classic,docusaurus.core,docusaurus.plugin-debug,docusaurus.theme-mermaid,docusaurus.theme-live-codeblock,docusaurus.theme-search-algolia.docsearch,docusaurus.theme-search-algolia;@layer docusaurus.infima{.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:#0000;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:#0000000d;--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 #0000001a;--ifm-global-shadow-md:0 5px 40px #0003;--ifm-global-shadow-tl:0 12px 28px 0 #0003,0 2px 4px 0 #0000001a;--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:#0000;--ifm-table-stripe-background:#00000008;--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:#0000}*{box-sizing:border-box}html{background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);-webkit-font-smoothing:antialiased;-webkit-tap-highlight-color:transparent;text-rendering:optimizelegibility;-webkit-text-size-adjust:100%;text-size-adjust:100%}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid #0000001a;border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:initial;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;display:block;margin-bottom:var(--ifm-spacing-vertical)}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){-webkit-text-decoration:none;text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom)}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.text--primary{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.alert__heading,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{list-style:none;padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:#3578e526;--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:#ebedf026;--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:#00a40026;--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:#54c7ec26;--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:#ffba0026;--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:#fa383e26;--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:any-link:hover,.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);-webkit-text-decoration:none;text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;-webkit-user-select:none;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:#0000;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.dropdown__link--active,.dropdown__link:hover,.menu__link:hover,.navbar__brand:hover,.navbar__link--active,.navbar__link:hover,.pagination-nav__link:hover,.pagination__link:hover{-webkit-text-decoration:none;text-decoration:none}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);-webkit-text-decoration:none;text-decoration:none}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}.dropdown__menu,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;list-style:none;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color)}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor #0000;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.footer__item{margin-top:0}.footer__items{margin-bottom:0}[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{list-style:none;margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color)}.menu__caret:before,.menu__link--sublist-caret:after{content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;left:0;opacity:0;position:fixed;top:0;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;visibility:hidden}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color)}.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color)}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:#ffffff1a;--ifm-navbar-search-input-placeholder-color:#ffffff80;color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:#ffffff0d;--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:1rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:#0009;right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav{display:grid;grid-gap:var(--ifm-spacing-horizontal);gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover)}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto;padding-left:0}.tabs__item{border-bottom:3px solid #0000;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:#ffffff0d;--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:#ffffff1a;--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:#ffffff12;--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec}}.bharatml-hero .bharatml-button:hover,.bharatml-hero .button--outline:hover,[data-theme=dark] .bharatml-hero .bharatml-button:hover,[data-theme=dark] .bharatml-hero .button--outline:hover{background-color:#fff!important;border-color:#fff!important;color:var(--bharatml-primary)!important}.bharatml-hero .bharatml-button,.bharatml-hero .button--outline{border:2px solid #fff!important;color:#fff!important;transition:.3s}:root{--ifm-color-primary:#450839;--ifm-color-primary-dark:#3d0732;--ifm-color-primary-darker:#39062f;--ifm-color-primary-darkest:#2f0527;--ifm-color-primary-light:#4d0940;--ifm-color-primary-lighter:#510a43;--ifm-color-primary-lightest:#5d0c4d;--ifm-code-font-size:95%;--docusaurus-highlighted-code-line-bg:#0000001a;--bharatml-primary:#450839;--bharatml-primary-hover:#6a0c59;--bharatml-secondary:#f9f9f9;--bharatml-text:#1c1e21;--bharatml-text-light:#606770}[data-theme=dark]{--ifm-color-primary:#8b4582;--ifm-color-primary-dark:#7d3f75;--ifm-color-primary-darker:#763c6e;--ifm-color-primary-darkest:#62315a;--ifm-color-primary-light:#994b8f;--ifm-color-primary-lighter:#a04e96;--ifm-color-primary-lightest:#b657a9;--docusaurus-highlighted-code-line-bg:#0000004d;--bharatml-primary:#8b4582;--bharatml-primary-hover:#a04e96;--bharatml-secondary:#1e1e1e;--bharatml-text:#e3e3e3;--bharatml-text-light:#b4b4b4}.bharatml-hero{background:linear-gradient(135deg,var(--bharatml-primary) 0,var(--bharatml-primary-hover) 100%);color:#fff}.bharatml-hero .bharatml-button{background-color:var(--bharatml-primary)}.bharatml-hero .button--outline{background-color:initial!important}[data-theme=dark] .bharatml-hero .bharatml-button{background-color:var(--bharatml-primary);border:2px solid #fff!important;color:#fff!important}[data-theme=dark] .bharatml-hero .button--outline{background-color:initial!important;border:2px solid #fff!important;color:#fff!important}.bharatml-button{background-color:var(--bharatml-primary);border-color:var(--bharatml-primary);transition:.3s}.bharatml-button:hover{background-color:var(--bharatml-primary-hover);border-color:var(--bharatml-primary-hover);color:#fff}.bharatml-card{background:#fff;border:1px solid #4508391a;border-radius:8px;padding:2rem;transition:.3s}.bharatml-card:hover{border-color:var(--bharatml-primary);box-shadow:0 4px 20px #4508391a;transform:translateY(-2px)}.bharatml-icon{align-items:center;background:linear-gradient(135deg,var(--bharatml-primary),var(--bharatml-primary-hover));border-radius:12px;color:#fff;display:flex;font-size:1.5rem;height:64px;justify-content:center;margin:0 auto 1rem;width:64px}@layer docusaurus.core{#__docusaurus-base-url-issue-banner-container{display:none}}.aboutSection_udvw,.features_t9lD{background-color:var(--ifm-background-surface-color)}.featuresHeader_qR2i,.features_t9lD h3{color:var(--bharatml-primary);margin-bottom:1rem}.features_t9lD{display:block;padding:4rem 0;text-align:center;width:100%}.featureSvg_GfXr{height:200px;width:200px}.featuresHeader_qR2i{font-size:2.5rem;font-weight:700;text-align:center}.featuresSubtitle_VdGe{color:var(--ifm-font-color-base);font-size:1.2rem;opacity:1;text-align:center}.features_t9lD .bharatml-card_xZ6l{height:100%;margin-top:1rem}.features_t9lD .bharatml-icon_XBoJ{margin-bottom:1.5rem}.features_t9lD h3{font-size:1.25rem;font-weight:600}.features_t9lD p{color:var(--ifm-font-color-base)!important;font-size:.95rem;font-weight:400;line-height:1.6;margin:0}.featureDescription_sP1D{color:#1c1e21!important;font-size:.95rem!important;font-weight:400!important;line-height:1.6!important;margin:0!important}[data-theme=dark] .bharatml-card_xZ6l{background:#2a2a2a!important;border-color:#8b45824d;color:#fff}[data-theme=dark] .bharatml-card_xZ6l:hover{background:#333!important;border-color:var(--bharatml-primary);box-shadow:0 4px 20px #8b45824d}[data-theme=dark] .featureDescription_sP1D,[data-theme=dark] .featuresHeader_qR2i,[data-theme=dark] .features_t9lD h3,[data-theme=dark] .features_t9lD p{color:#a04e96!important}[data-theme=dark] .featuresSubtitle_VdGe{color:#e0e0e0!important}.heroBanner_qdFl{overflow:hidden;padding:4rem 0;position:relative;text-align:center}.logoContainer_xdaK{align-items:center;display:flex;justify-content:center;margin-bottom:2rem}.heroLogo_U6bI{filter:drop-shadow(0 4px 8px rgba(0,0,0,.1));height:180px;transition:transform .3s;width:180px}.heroLogo_U6bI:hover{transform:scale(1.05)}.buttons_AeoN{align-items:center;gap:1rem;margin-bottom:2rem}.buttons_AeoN,.statsContainer_KpvY{display:flex;justify-content:center}.statsContainer_KpvY{gap:3rem;margin-top:2rem;opacity:.9}.statItem_bwiZ{align-items:center;color:#fff;display:flex;flex-direction:column;text-align:center}.statItem_bwiZ strong{display:block;font-size:1.5rem;font-weight:700;margin-bottom:.25rem}.statItem_bwiZ span{font-size:.875rem;letter-spacing:.5px;opacity:.8;text-transform:uppercase}.aboutSection_udvw{padding:4rem 0}.highlightBox_Uhe8{background:linear-gradient(135deg,#f8f9ff,#e8f0ff);border:1px solid #4508391a;border-radius:12px;height:100%;padding:2rem}.highlightBox_Uhe8 h3{color:var(--bharatml-primary);font-size:1.25rem;margin-bottom:1rem}.highlightBox_Uhe8 li,[data-theme=dark] .highlightBox_Uhe8 li{color:var(--bharatml-text)}.highlightBox_Uhe8 ul{list-style:none;margin:0;padding:0}.highlightBox_Uhe8 li{font-size:.95rem;padding:.5rem 0}.highlightBox_Uhe8 li:not(:last-child){border-bottom:1px solid #4508390d}[data-theme=dark] .highlightBox_Uhe8{background:linear-gradient(135deg,#1a1a2e,#16213e);border-color:#8b458233}@layer docusaurus.theme-common{body:not(.navigation-with-keyboard) :not(input):focus{outline:0}.themedComponent_mlkZ{display:none}[data-theme=dark] .themedComponent--dark_xIcU,[data-theme=light] .themedComponent--light_NVdE,html:not([data-theme]) .themedComponent--light_NVdE{display:initial}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.errorBoundaryFallback_VBag{color:red;padding:.55rem}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;list-style:none;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:#0000 #0000 #0000 var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before{transform:rotate(90deg)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.collapsibleContent_i85q p:last-child,.details_lb9f>summary>p:last-child{margin-bottom:0}}@layer docusaurus.theme-classic{:root{--docusaurus-progress-bar-color:var(--ifm-color-primary);--docusaurus-announcement-bar-height:auto;--docusaurus-collapse-button-bg:#0000;--docusaurus-collapse-button-bg-hover:#0000001a;--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px;--docusaurus-blog-social-icon-size:1rem;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300)}#nprogress{pointer-events:none}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;left:0;position:fixed;top:0;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit;-webkit-text-decoration:underline;text-decoration:underline}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}.docSidebarContainer_YfHR,.navbarSearchContainer_Bca1:empty,.sidebarLogo_isFc,.toggleIcon_g3eP,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.announcementBarContent_xLdY{flex:1 1 auto}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{-webkit-tap-highlight-color:transparent;align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}[data-theme-choice=dark] .darkToggleIcon_wfgR,[data-theme-choice=light] .lightToggleIcon_pyhR,[data-theme-choice=system] .systemToggleIcon_QzmC{display:initial}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}[data-theme=dark]:root{--docusaurus-collapse-button-bg:#ffffff0d;--docusaurus-collapse-button-bg-hover:#ffffff1a}.collapseSidebarButton_PEFL{display:none;margin:0}.iconExternalLink_nPIU{margin-left:.3rem}.dropdownNavbarItemMobile_J0Sd{cursor:pointer}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.navbar__items--right>:last-child{padding-right:0}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.menuExternalLink_NmtK{align-items:center}.docMainContainer_TBSr,.docRoot_UBD9{display:flex;width:100%}.authorSocialIcon_XYv3,.authorSocialLink_owbf{width:var(--docusaurus-blog-social-icon-size)}.docsWrapper_hBAB{display:flex;flex:1 0 auto}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);-webkit-user-select:none;user-select:none}.hash-link:before{content:"#"}.docCardListItem_W1sv>*,body,html{height:100%}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.sidebar_re4s{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 2rem)}.authorSocials_rSDt,.authorTitle_nd0D{overflow:hidden;-webkit-box-orient:vertical}.sidebarItemTitle_pO2u{font-size:var(--ifm-h3-font-size);font-weight:var(--ifm-font-weight-bold)}.container_mt6G,.sidebarItemList_Yudw{font-size:.9rem}.sidebarItem__DBe{margin-top:.7rem}.sidebarItemLink_mo7H{color:var(--ifm-font-color-base);display:block}.sidebarItemLink_mo7H:hover{-webkit-text-decoration:none;text-decoration:none}.sidebarItemLinkActive_I1ZP{color:var(--ifm-color-primary)!important}.yearGroupHeading_rMGB{margin-bottom:.4rem;margin-top:1.6rem}.yearGroupHeading_QT03{margin:1rem .75rem .5rem}.cardContainer_fWXF{--ifm-link-color:var(--ifm-color-emphasis-800);--ifm-link-hover-color:var(--ifm-color-emphasis-700);--ifm-link-hover-decoration:none;border:1px solid var(--ifm-color-emphasis-200);box-shadow:0 1.5px 3px 0 #00000026;transition:all var(--ifm-transition-fast) ease;transition-property:border,box-shadow}.cardContainer_fWXF:hover{border-color:var(--ifm-color-primary);box-shadow:0 3px 6px 0 #0003}.admonitionContent_BuS1>:last-child,.cardContainer_fWXF :last-child{margin-bottom:0}.cardTitle_rnsV{font-size:1.2rem}.cardDescription_PWke{font-size:.8rem}.docCardListItem_W1sv{margin-bottom:2rem}.title_f1Hy{font-size:3rem}[data-theme=dark] .githubSvg_Uu4N,[data-theme=dark] .instagramSvg_YC40,[data-theme=dark] .threadsSvg_PTXY,[data-theme=dark] .xSvg_y3PF{fill:var(--light)}[data-theme=light] .githubSvg_Uu4N,[data-theme=light] .instagramSvg_YC40,[data-theme=light] .threadsSvg_PTXY,[data-theme=light] .xSvg_y3PF{fill:var(--dark)}.authorSocials_rSDt{align-items:center;display:flex;flex-wrap:wrap;line-clamp:1;-webkit-line-clamp:1}.authorSocialLink_owbf,.authorSocials_rSDt{height:var(--docusaurus-blog-social-icon-size);line-height:0}.authorSocialLink_owbf{margin-right:.4rem}.authorSocialIcon_XYv3{height:var(--docusaurus-blog-social-icon-size)}.authorImage_XqGP{--ifm-avatar-photo-size:3.6rem}.author-as-h1_n9oJ .authorImage_XqGP{--ifm-avatar-photo-size:7rem}.author-as-h2_gXvM .authorImage_XqGP{--ifm-avatar-photo-size:5.4rem}.authorDetails_lV9A{align-items:flex-start;display:flex;flex-direction:column;justify-content:space-around}.authorName_yefp{display:flex;flex-direction:row;font-size:1.1rem;line-height:1.1rem}.author-as-h1_n9oJ .authorName_yefp{display:inline;font-size:2.4rem;line-height:2.4rem}.author-as-h2_gXvM .authorName_yefp{display:inline;font-size:1.4rem;line-height:1.4rem}.authorTitle_nd0D{display:-webkit-box;font-size:.8rem;line-height:1rem;line-clamp:1;-webkit-line-clamp:1}.author-as-h1_n9oJ .authorTitle_nd0D{font-size:1.2rem;line-height:1.6rem}.author-as-h2_gXvM .authorTitle_nd0D{font-size:1rem;line-height:1.3rem}.authorBlogPostCount_iiJ5{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.8rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.authorListItem_n3yI{list-style-type:none;margin-bottom:2rem}.authorCol_Hf19{max-width:inherit!important}.imageOnlyAuthorRow_pa_O{display:flex;flex-flow:row wrap}.imageOnlyAuthorCol_G86a{margin-left:.3rem;margin-right:.3rem}.codeBlockContainer_Ckt0{background:var(--prism-background-color);border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);color:var(--prism-color);margin-bottom:var(--ifm-leading)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockStandalone_MEMb{padding:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.theme-code-block:hover .copyButtonCopied_Vdqa{opacity:1!important}.copyButtonIcons_IEyt{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_TrPX,.copyButtonSuccessIcon_cVMy{left:0;position:absolute;top:0;fill:currentColor;height:inherit;opacity:inherit;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_cVMy{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_Vdqa .copyButtonIcon_TrPX{opacity:0;transform:scale(.33)}.copyButtonCopied_Vdqa .copyButtonSuccessIcon_cVMy{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.wordWrapButtonIcon_b1P5{height:1.2rem;width:1.2rem}.wordWrapButtonEnabled_uzNF .wordWrapButtonIcon_b1P5{color:var(--ifm-color-primary)}.buttonGroup_M5ko{column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup_M5ko button{align-items:center;background:var(--prism-background-color);border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);color:var(--prism-color);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup_M5ko button:focus-visible,.buttonGroup_M5ko button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup_M5ko button{opacity:.4}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);-webkit-text-decoration:none;text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tag_Nnez{display:inline-block;margin:.5rem .5rem 0 1rem}.codeBlockContent_QJqH{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_OeMC{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlockTitle_OeMC+.codeBlockContent_QJqH .codeBlock_a8dz{border-top-left-radius:0;border-top-right-radius:0}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}.lastUpdated_JAkA{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.tocCollapsibleContent_vkbj a{display:block}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.containsTaskList_mC6p{list-style:none}:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.img_ev3q{height:auto}.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.admonition_xJq3{margin-bottom:1em}.admonitionHeading_Gvgb{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);text-transform:uppercase}.admonitionHeading_Gvgb:not(:last-child){margin-bottom:.3rem}.admonitionHeading_Gvgb code{text-transform:none}.admonitionIcon_Rf37{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_Rf37 svg{display:inline-block;height:1.6em;width:1.6em;fill:var(--ifm-alert-foreground-color)}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}.title_kItE{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-leading)*1.25)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*{margin-top:0}.mdxPageWrapper_j9I6{justify-content:center}}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_TmdG{background-color:var(--docusaurus-collapse-button-bg)}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_i1dp,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_TmdG:focus,.expandButton_TmdG:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.navbarSearchContainer_Bca1{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);-webkit-text-decoration:none!important;text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_TmdG{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_i1dp{transform:rotate(180deg)}.docSidebarContainer_YfHR{border-right:1px solid var(--ifm-toc-border-color);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_DPk8{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_aRkj{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_TBSr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_lQrH{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_JWYK{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}.lastUpdated_JAkA{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn,.generatedIndexPage_vN6x{max-width:75%!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.sidebar_re4s,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block;width:max-content}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.navbarSearchContainer_Bca1{position:absolute;right:var(--ifm-navbar-padding-horizontal)}.docItemContainer_F8PC{padding:0 .3rem}}@media screen and (max-width:996px){.features_t9lD .bharatml-card_xZ6l{margin-bottom:2rem}.featuresHeader_qR2i{font-size:2rem}.featuresSubtitle_VdGe{font-size:1rem}.heroBanner_qdFl{padding:2rem}}@media screen and (max-width:768px){.heroLogo_U6bI{height:120px;width:120px}.logoContainer_xdaK{margin-bottom:1.5rem}.buttons_AeoN{flex-direction:column;gap:.5rem}.statsContainer_KpvY{align-items:center;flex-direction:column;gap:1rem}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}.title_f1Hy{font-size:2rem}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file diff --git a/docs/assets/images/bharatmlstack-72e1796337bfa224dee2a0f59ec4e2da.png b/docs/assets/images/bharatmlstack-72e1796337bfa224dee2a0f59ec4e2da.png deleted file mode 100644 index 3559779f..00000000 Binary files a/docs/assets/images/bharatmlstack-72e1796337bfa224dee2a0f59ec4e2da.png and /dev/null differ diff --git a/docs/assets/images/bms-7399e8796d2cd24617c432518ce3f312.png b/docs/assets/images/bms-7399e8796d2cd24617c432518ce3f312.png new file mode 100644 index 00000000..b397fc88 Binary files /dev/null and b/docs/assets/images/bms-7399e8796d2cd24617c432518ce3f312.png differ diff --git a/docs/assets/images/interaction-str-d9e7aefea121aefb4e94c6c9f060d016.png b/docs/assets/images/interaction-str-d9e7aefea121aefb4e94c6c9f060d016.png new file mode 100644 index 00000000..99ddd4e9 Binary files /dev/null and b/docs/assets/images/interaction-str-d9e7aefea121aefb4e94c6c9f060d016.png differ diff --git a/docs/assets/images/llm-plat-9ac69c0ffd8c387d177e582611b8c775.png b/docs/assets/images/llm-plat-9ac69c0ffd8c387d177e582611b8c775.png new file mode 100644 index 00000000..1f0fa9f7 Binary files /dev/null and b/docs/assets/images/llm-plat-9ac69c0ffd8c387d177e582611b8c775.png differ diff --git a/docs/assets/images/mp-dag-976ff51caf25f09d977ccc10e70918f3.png b/docs/assets/images/mp-dag-976ff51caf25f09d977ccc10e70918f3.png new file mode 100644 index 00000000..4a13af56 Binary files /dev/null and b/docs/assets/images/mp-dag-976ff51caf25f09d977ccc10e70918f3.png differ diff --git a/docs/assets/images/mp-matrix-43994f433f78905ccbd10cfe284f3c9f.png b/docs/assets/images/mp-matrix-43994f433f78905ccbd10cfe284f3c9f.png new file mode 100644 index 00000000..44b21256 Binary files /dev/null and b/docs/assets/images/mp-matrix-43994f433f78905ccbd10cfe284f3c9f.png differ diff --git a/docs/assets/images/v1.0.0-inferflow-arch-bce54b3b4f7d3be68fa22dc204529f53.png b/docs/assets/images/v1.0.0-inferflow-arch-bce54b3b4f7d3be68fa22dc204529f53.png new file mode 100644 index 00000000..acad4888 Binary files /dev/null and b/docs/assets/images/v1.0.0-inferflow-arch-bce54b3b4f7d3be68fa22dc204529f53.png differ diff --git a/docs/assets/images/v1.0.0-inferflow-dag-matrix-0f13b51422587e6099cf4ee783844db1.png b/docs/assets/images/v1.0.0-inferflow-dag-matrix-0f13b51422587e6099cf4ee783844db1.png new file mode 100644 index 00000000..2345d69f Binary files /dev/null and b/docs/assets/images/v1.0.0-inferflow-dag-matrix-0f13b51422587e6099cf4ee783844db1.png differ diff --git a/docs/assets/images/vss-c482f6eac4c68b3219e4c562a6b717ec.png b/docs/assets/images/vss-c482f6eac4c68b3219e4c562a6b717ec.png new file mode 100644 index 00000000..c6b18475 Binary files /dev/null and b/docs/assets/images/vss-c482f6eac4c68b3219e4c562a6b717ec.png differ diff --git a/docs/assets/js/00b12b9c.ea8fba0b.js b/docs/assets/js/00b12b9c.ea8fba0b.js new file mode 100644 index 00000000..179d11b7 --- /dev/null +++ b/docs/assets/js/00b12b9c.ea8fba0b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7048],{1106:e=>{e.exports=JSON.parse('{"permalink":"/BharatMLStack/blog/post-two","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-two/index.md","source":"@site/blog/bharatmlstack-history/post-two/index.md","title":"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)","description":"BharatMLStack","date":"2023-04-10T00:00:00.000Z","tags":[{"inline":true,"label":"inferflow","permalink":"/BharatMLStack/blog/tags/inferflow"},{"inline":true,"label":"interaction-store","permalink":"/BharatMLStack/blog/tags/interaction-store"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"},{"inline":true,"label":"bharatmlstack","permalink":"/BharatMLStack/blog/tags/bharatmlstack"}],"readingTime":6.31,"hasTruncateMarker":false,"authors":[{"name":"Bhawani Singh","title":"Architect @ Meesho","url":"https://github.com/singh-bhawani","imageURL":"https://github.com/singh-bhawani.png","key":"bhawani","page":null},{"name":"Jigar Dave","title":"Lead Software Engineer @ Meesho","url":"https://github.com/jigarpatel26","imageURL":"https://github.com/jigarpatel26.png","key":"jigar","page":null},{"name":"Adarsha Das","title":"Senior Architect @ Meesho","url":"https://github.com/a0d00kc","imageURL":"https://github.com/a0d00kc.png","key":"adarsha","page":null}],"frontMatter":{"slug":"post-two","title":"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)","authors":["bhawani","jigar","adarsha"],"date":"2023-4-10","tags":["inferflow","interaction-store","mlplatform","meesho","bharatmlstack"]},"unlisted":false,"prevItem":{"title":"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search","permalink":"/BharatMLStack/blog/post-three"},"nextItem":{"title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","permalink":"/BharatMLStack/blog/post-one"}}')},3086:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/bms-7399e8796d2cd24617c432518ce3f312.png"},4114:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/mp-dag-976ff51caf25f09d977ccc10e70918f3.png"},8111:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/mp-matrix-43994f433f78905ccbd10cfe284f3c9f.png"},8453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var i=t(6540);const r={},s=i.createContext(r);function a(e){const n=i.useContext(s);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(s.Provider,{value:n},e.children)}},8517:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var i=t(1106),r=t(4848),s=t(8453);const a={slug:"post-two",title:"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)",authors:["bhawani","jigar","adarsha"],date:"2023-4-10",tags:["inferflow","interaction-store","mlplatform","meesho","bharatmlstack"]},o=void 0,l={authorsImageUrls:[void 0,void 0,void 0]},c=[{value:"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)",id:"building-meeshos-ml-platform-lessons-from-the-first-gen-system-part-2",level:2},{value:"The Cost of Success",id:"the-cost-of-success",level:3},{value:"Scaling Pains (and Cassandra\u2019s Limits)",id:"scaling-pains-and-cassandras-limits",level:3},{value:"Interaction Store Woes",id:"interaction-store-woes",level:3},{value:"Silver Linings",id:"silver-linings",level:3},{value:"Round Two: Solving the Top 2 Bottlenecks",id:"round-two-solving-the-top-2-bottlenecks",level:3},{value:"Problem 1: No-Code Feature Retrieval for Model Inference",id:"problem-1-no-code-feature-retrieval-for-model-inference",level:4},{value:"Problem 2: Scaling Without Breaking the Bank",id:"problem-2-scaling-without-breaking-the-bank",level:4},{value:"Optimizing the Online Feature Store",id:"optimizing-the-online-feature-store",level:4},{value:"Optimizing the Interaction Store",id:"optimizing-the-interaction-store",level:4},{value:"Results",id:"results",level:4},{value:"The Catch: Our ML Hosting Hit a Hard Limit",id:"the-catch-our-ml-hosting-hit-a-hard-limit",level:4},{value:"Conclusion: From Firefighting to Future-Proofing",id:"conclusion-from-firefighting-to-future-proofing",level:3}];function d(e){const n={h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",ol:"ol",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"BharatMLStack",src:t(3086).A+"",width:"1396",height:"460"})}),"\n",(0,r.jsx)(n.h2,{id:"building-meeshos-ml-platform-lessons-from-the-first-gen-system-part-2",children:"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)"}),"\n",(0,r.jsx)(n.p,{children:"By late 2022, we had built something we were truly proud of\u2014a real-time ML serving system with a DAG-based executor, a feature store, and an interaction store powering key ranking and personalization models. It was a major milestone, the culmination of months of effort from data scientists, ML engineers, and backend teams. Our system was live, and we were ready to push the boundaries of experimentation.\nAnd it worked. Mostly.\nBut soon, cracks appeared. Every new model needed custom feature retrieval logic, DAGs became dense and unmanageable, and scaling turned into a constant firefight. Costs surged, and infra bottlenecks slowed experimentation. Our system worked, but it wasn\u2019t built for scale.\nThis is the story of how we tackled these challenges\u2014building Inferflow for seamless feature retrieval, optimizing real-time infra, and cutting costs while scaling to millions of QPS."}),"\n",(0,r.jsx)(n.h3,{id:"the-cost-of-success",children:"The Cost of Success"}),"\n",(0,r.jsx)(n.p,{children:"Every new Ranker model required its own feature set, often pulling from different entities. Each addition meant:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Adding new DAG nodes in IOP"}),"\n",(0,r.jsx)(n.li,{children:"Writing custom logic to fetch features from multiple sources (e.g., user, product, user \xd7 category)"}),"\n",(0,r.jsx)(n.li,{children:"Inferring intermediate features (e.g., extracting category from a product to fetch user \xd7 category data)"}),"\n",(0,r.jsx)(n.li,{children:"Optimizing I/O and dealing with the inevitable bugs"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"What began as clean DAGs soon turned into a tangled web of cross-dependent graphs. Every experimentation cycle meant new nodes, new dependencies, and slower iterations."}),"\n",(0,r.jsx)(n.h3,{id:"scaling-pains-and-cassandras-limits",children:"Scaling Pains (and Cassandra\u2019s Limits)"}),"\n",(0,r.jsx)(n.p,{children:"At some point, we were hitting:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"250\u2013300K reads/sec"}),"\n",(0,r.jsx)(n.li,{children:"1M writes/sec (during lean hours)"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"All of this ran on Cassandra. While its distributed architecture had been proven in production, operating large-scale clusters came with considerable infrastructure overhead. Our proof-of-concept (POC) demonstrated throughput of around 100K ops/sec, but as we scaled further, the challenges grew. Ensuring node health, optimizing compaction, and maintaining storage balance became increasingly demanding. We also observed latency spikes under heavy load, alongside a sharp increase in total cost of ownership."}),"\n",(0,r.jsx)(n.h3,{id:"interaction-store-woes",children:"Interaction Store Woes"}),"\n",(0,r.jsx)(n.p,{children:"Our interaction store was another ticking time bomb:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\ud83d\udea8 Clusters kept growing in size and cost"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\udea8 Latency spikes became increasingly frequent"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\udea8 The DMC proxy occasionally lost locality of nodes against shards, causing cross-node communication and degraded performance"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Each time this happened, we had to manually rebalance shards just to restore stable latency, making operations unsustainable at scale."}),"\n",(0,r.jsx)(n.h3,{id:"silver-linings",children:"Silver Linings"}),"\n",(0,r.jsx)(n.p,{children:"Despite the chaos, the system was live and delivering value:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Real-time infrastructure was in production"}),"\n",(0,r.jsx)(n.li,{children:"Costs dropped by 60\u201370% compared to offline personalization"}),"\n",(0,r.jsx)(n.li,{children:"New experiments rolled out faster and more successfully"}),"\n",(0,r.jsx)(n.li,{children:"User engagement metrics improved"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"It wasn\u2019t perfect. It was far from easy. But it worked\u2014and that counted for a lot."}),"\n",(0,r.jsx)(n.h3,{id:"round-two-solving-the-top-2-bottlenecks",children:"Round Two: Solving the Top 2 Bottlenecks"}),"\n",(0,r.jsx)(n.p,{children:"With the first-gen system stretched to its limits, we stepped back. Conversations with data scientists and backend engineers revealed three recurring pain points:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Coding feature retrieval logic for every new model was becoming unsustainable"}),"\n",(0,r.jsx)(n.li,{children:"ML scale was exploding\u2014bringing rising infra costs with it"}),"\n",(0,r.jsx)(n.li,{children:"Real-time embedding search was the next big unlock"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"We tackled them one by one\u2014starting with the biggest pain point."}),"\n",(0,r.jsx)(n.h4,{id:"problem-1-no-code-feature-retrieval-for-model-inference",children:"Problem 1: No-Code Feature Retrieval for Model Inference"}),"\n",(0,r.jsx)(n.p,{children:"We noticed a pattern: for personalized ranking, models needed features from:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\u2705 Product"}),"\n",(0,r.jsx)(n.li,{children:"\u2705 User"}),"\n",(0,r.jsx)(n.li,{children:"\u2705 User \xd7 Category"}),"\n",(0,r.jsx)(n.li,{children:"\u2705 Region, cohort, sub-category, etc."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"A key insight emerged: Entities that contribute features for a model always map back to the context entities."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"MP Dag",src:t(4114).A+"",width:"1272",height:"512"})}),"\n",(0,r.jsx)(n.p,{children:"With this, we designed Inferflow, a graph-driven feature retrieval and model orchestration system:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"1\ufe0f\u20e3 Inferflow takes a modelId and context IDs (e.g., userId, productIds)"}),"\n",(0,r.jsx)(n.li,{children:"2\ufe0f\u20e3 Loads a pre-defined feature retrieval graph from ZooKeeper"}),"\n",(0,r.jsx)(n.li,{children:"3\ufe0f\u20e3 Executes the graph to resolve entity relationships dynamically"}),"\n",(0,r.jsx)(n.li,{children:"4\ufe0f\u20e3 Outputs a 2D matrix of feature vectors"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"\ud83d\udca1 The impact?"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\ud83d\ude80 No more custom feature retrieval code\u2014just graph updates in config"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\ude80 Feature consistency across experiments"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\ude80 Faster iteration cycles for ranking, fraud detection, and beyond"}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Here\u2019s a visual example that shows how this graph plays out during execution. We further extended the graph to call multiple models as needed:\n",(0,r.jsx)(n.img,{alt:"MP matrix",src:t(8111).A+"",width:"1262",height:"768"}),"\nWe built Inferflow in GoLang, using gRPC and Proto3 serialization for efficiency."]}),"\n",(0,r.jsx)(n.h4,{id:"problem-2-scaling-without-breaking-the-bank",children:"Problem 2: Scaling Without Breaking the Bank"}),"\n",(0,r.jsx)(n.p,{children:"With more ML use cases coming online, we needed to cut costs without compromising performance. We focused on:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\ud83d\udd39 Online Feature Store"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\udd39 Interaction Store"}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"optimizing-the-online-feature-store",children:"Optimizing the Online Feature Store"}),"\n",(0,r.jsx)(n.p,{children:"Our costs were concentrated in:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\ud83d\udccc Database (Cassandra)"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\udccc Cache (Redis)"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\udccc Running Pods (Java services)"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"1\ufe0f\u20e3 Replacing Cassandra with ScyllaDB\nAs we hit the operational limits of large Cassandra clusters, we transitioned to ScyllaDB, which offered a seamless drop-in replacement without major code changes. The switch brought significant benefits:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Throughput: Matched or exceeded Cassandra's performance under identical workloads, even under high concurrency."}),"\n",(0,r.jsx)(n.li,{children:"Latency: Achieved consistently lower P99 latencies due to ScyllaDB's shard-per-core architecture and better I/O utilization."}),"\n",(0,r.jsx)(n.li,{children:"Cost Efficiency: Reduced infra footprint by ~70% through better CPU and memory efficiency, eliminating the need for over-provisioned nodes."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"2\ufe0f\u20e3 Finding the Right Cache\nTo reduce backend load and improve response times, we benchmarked multiple caching solutions\u2014Memcached, KeyDB, and Dragonfly\u2014under real production traffic patterns. Dragonfly stood out due to its robust architecture and operational simplicity:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Data Skew Handling: Efficiently managed extreme key hotness and uneven access patterns without performance degradation."}),"\n",(0,r.jsx)(n.li,{children:"Throughput: Delivered consistently high throughput, even with large object sizes and concurrent access."}),"\n",(0,r.jsx)(n.li,{children:"Ease of Adoption: Acted as a drop-in Redis replacement with full protocol compatibility\u2014no changes needed in application code or client libraries."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"3\ufe0f\u20e3 Moving to GoLang for Cost-Efficient Serving\nJava services were memory-heavy\u2014so we rewrote core services in GoLang. The results?"}),"\n",(0,r.jsx)(n.p,{children:"\u2705 Memory usage dropped by ~80%\n\u2705 CPU utilization was significantly lower\n\u2705 Faster, more efficient deployments"}),"\n",(0,r.jsx)(n.h4,{id:"optimizing-the-interaction-store",children:"Optimizing the Interaction Store"}),"\n",(0,r.jsx)(n.p,{children:"We realized that we only need a user\u2019s interaction data in Redis when they open the app. So, we implemented a tiered storage approach:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\ud83d\udccc Cold Tier (ScyllaDB)\u2014Stores click, order, wishlist events"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\udccc Hot Tier (Redis)\u2014Loads a user\u2019s past interactions only when they open the app"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Smart Offloading: We introduced an inactivity tracker to detect when a user session ends. At that point, Redis data was flushed back to Scylla, reducing unnecessary writes."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"InteractionStore",src:t(9758).A+"",width:"1242",height:"572"})}),"\n",(0,r.jsx)(n.h4,{id:"results",children:"Results"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Online Feature Store hit 1M QPS for the first time during the 2023 Mega Blockbuster Sale\u2014without breaking a sweat"}),"\n",(0,r.jsx)(n.li,{children:"Infra costs for Online Feature Store and Interaction Store dropped by ~60%"}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"the-catch-our-ml-hosting-hit-a-hard-limit",children:"The Catch: Our ML Hosting Hit a Hard Limit"}),"\n",(0,r.jsx)(n.p,{children:"While planning for 2023 MBS, we ran into a critical scalability bottleneck:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\u274c Insufficient compute availability in our region for ML instances"}),"\n",(0,r.jsx)(n.li,{children:"\u274c Couldn\u2019t provision enough nodes to handle real-time inference at scale"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"This forced us to rethink where and how we hosted our models. The existing setup was great for prototyping\u2014but it wasn\u2019t built to handle the bursty, high-QPS demands of real-world production workloads."}),"\n",(0,r.jsx)(n.h3,{id:"conclusion-from-firefighting-to-future-proofing",children:"Conclusion: From Firefighting to Future-Proofing"}),"\n",(0,r.jsx)(n.p,{children:"What started as an ambitious experiment turned into a real-time ML infrastructure that powered millions of requests per second. We battled scaling pains, rethought feature retrieval with Inferflow, and rebuilt our infra stack for efficiency\u2014driving down costs while improving experimentation velocity.\nBut new challenges emerged. Our infrastructure could now handle scale, but our ML model hosting setup hit a hard limit. With compute availability bottlenecks threatening real-time inference, we faced a critical decision: how do we make model serving as scalable and cost-efficient as the rest of our stack? That\u2019s the next piece of the puzzle\u2014and the story of Part 3."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},9758:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/interaction-str-d9e7aefea121aefb4e94c6c9f060d016.png"}}]); \ No newline at end of file diff --git a/docs/assets/js/01a85c17.5487421a.js b/docs/assets/js/01a85c17.5487421a.js deleted file mode 100644 index a84c5428..00000000 --- a/docs/assets/js/01a85c17.5487421a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8209],{4096:(e,t,a)=>{a.d(t,{in:()=>c,OU:()=>P,Ki:()=>y,kJ:()=>b,x:()=>l,e7:()=>m,J_:()=>f,Gx:()=>A});var s=a(6540),n=a(9532),i=a(6803),r=a(4848);function l(){const e=(0,i.A)(),t=e?.data?.blogMetadata;if(!t)throw new Error("useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context");return t}const o=s.createContext(null);function c({children:e,content:t,isBlogPostPage:a=!1}){const n=function({content:e,isBlogPostPage:t}){return(0,s.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,toc:e.toc,isBlogPostPage:t})),[e,t])}({content:t,isBlogPostPage:a});return(0,r.jsx)(o.Provider,{value:n,children:e})}function m(){const e=(0,s.useContext)(o);if(null===e)throw new n.dV("BlogPostProvider");return e}var d=a(6025),u=a(4586);const g=e=>new Date(e).toISOString();function h(e){const t=e.map(x);return{author:1===t.length?t[0]:t}}function p(e,t,a){return e?{image:j({imageUrl:t(e,{absolute:!0}),caption:`title image for the blog post: ${a}`})}:{}}function b(e){const{siteConfig:t}=(0,u.A)(),{withBaseUrl:a}=(0,d.hH)(),{metadata:{blogDescription:s,blogTitle:n,permalink:i}}=e,r=`${t.url}${i}`;return{"@context":"https://schema.org","@type":"Blog","@id":r,mainEntityOfPage:r,headline:n,description:s,blogPost:e.items.map((e=>function(e,t,a){const{assets:s,frontMatter:n,metadata:i}=e,{date:r,title:l,description:o,lastUpdatedAt:c}=i,m=s.image??n.image,d=n.keywords??[],u=`${t.url}${i.permalink}`,b=c?g(c):void 0;return{"@type":"BlogPosting","@id":u,mainEntityOfPage:u,url:u,headline:l,name:l,description:o,datePublished:r,...b?{dateModified:b}:{},...h(i.authors),...p(m,a,l),...d?{keywords:d}:{}}}(e.content,t,a)))}}function f(){const e=l(),{assets:t,metadata:a}=m(),{siteConfig:s}=(0,u.A)(),{withBaseUrl:n}=(0,d.hH)(),{date:i,title:r,description:o,frontMatter:c,lastUpdatedAt:b}=a,f=t.image??c.image,x=c.keywords??[],j=b?g(b):void 0,N=`${s.url}${a.permalink}`;return{"@context":"https://schema.org","@type":"BlogPosting","@id":N,mainEntityOfPage:N,url:N,headline:r,name:r,description:o,datePublished:i,...j?{dateModified:j}:{},...h(a.authors),...p(f,n,r),...x?{keywords:x}:{},isPartOf:{"@type":"Blog","@id":`${s.url}${e.blogBasePath}`,name:e.blogTitle}}}function x(e){return{"@type":"Person",...e.name?{name:e.name}:{},...e.title?{description:e.title}:{},...e.url?{url:e.url}:{},...e.email?{email:e.email}:{},...e.imageURL?{image:e.imageURL}:{}}}function j({imageUrl:e,caption:t}){return{"@type":"ImageObject","@id":e,url:e,contentUrl:e,caption:t}}var N=a(6347),v=a(8774),C=a(1682),k=a(9169);function A(e){const{pathname:t}=(0,N.zy)();return(0,s.useMemo)((()=>e.filter((e=>function(e,t){return!(e.unlisted&&!(0,k.ys)(e.permalink,t))}(e,t)))),[e,t])}function y(e){const t=(0,C.$z)(e,(e=>`${new Date(e.date).getFullYear()}`)),a=Object.entries(t);return a.reverse(),a}function P({items:e,ulClassName:t,liClassName:a,linkClassName:s,linkActiveClassName:n}){return(0,r.jsx)("ul",{className:t,children:e.map((e=>(0,r.jsx)("li",{className:a,children:(0,r.jsx)(v.A,{isNavLink:!0,to:e.permalink,className:s,activeClassName:n,children:e.title})},e.permalink)))})}},6133:(e,t,a)=>{a.d(t,{A:()=>l});a(6540);var s=a(4164),n=a(8774);const i={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var r=a(4848);function l({permalink:e,label:t,count:a,description:l}){return(0,r.jsxs)(n.A,{rel:"tag",href:e,title:l,className:(0,s.A)(i.tag,a?i.tagWithCount:i.tagRegular),children:[t,a&&(0,r.jsx)("span",{children:a})]})}},8027:(e,t,a)=>{a.d(t,{A:()=>U});var s=a(6540),n=a(4164),i=a(1656),r=a(4581),l=a(1312),o=a(4096),c=a(6342),m=a(1107),d=a(4848);function u({year:e,yearGroupHeadingClassName:t,children:a}){return(0,d.jsxs)("div",{role:"group",children:[(0,d.jsx)(m.A,{as:"h3",className:t,children:e}),a]})}function g({items:e,yearGroupHeadingClassName:t,ListComponent:a}){if((0,c.p)().blog.sidebar.groupByYear){const s=(0,o.Ki)(e);return(0,d.jsx)(d.Fragment,{children:s.map((([e,s])=>(0,d.jsx)(u,{year:e,yearGroupHeadingClassName:t,children:(0,d.jsx)(a,{items:s})},e)))})}return(0,d.jsx)(a,{items:e})}const h=(0,s.memo)(g),p="sidebar_re4s",b="sidebarItemTitle_pO2u",f="sidebarItemList_Yudw",x="sidebarItem__DBe",j="sidebarItemLink_mo7H",N="sidebarItemLinkActive_I1ZP",v="yearGroupHeading_rMGB",C=({items:e})=>(0,d.jsx)(o.OU,{items:e,ulClassName:(0,n.A)(f,"clean-list"),liClassName:x,linkClassName:j,linkActiveClassName:N});function k({sidebar:e}){const t=(0,o.Gx)(e.items);return(0,d.jsx)("aside",{className:"col col--3",children:(0,d.jsxs)("nav",{className:(0,n.A)(p,"thin-scrollbar"),"aria-label":(0,l.T)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"}),children:[(0,d.jsx)("div",{className:(0,n.A)(b,"margin-bottom--md"),children:e.title}),(0,d.jsx)(h,{items:t,ListComponent:C,yearGroupHeadingClassName:v})]})})}const A=(0,s.memo)(k);var y=a(5600);const P="yearGroupHeading_QT03",_=({items:e})=>(0,d.jsx)(o.OU,{items:e,ulClassName:"menu__list",liClassName:"menu__list-item",linkClassName:"menu__link",linkActiveClassName:"menu__link--active"});function w({sidebar:e}){const t=(0,o.Gx)(e.items);return(0,d.jsx)(h,{items:t,ListComponent:_,yearGroupHeadingClassName:P})}function B(e){return(0,d.jsx)(y.GX,{component:w,props:e})}const G=(0,s.memo)(B);function O({sidebar:e}){const t=(0,r.l)();return e?.items.length?"mobile"===t?(0,d.jsx)(G,{sidebar:e}):(0,d.jsx)(A,{sidebar:e}):null}function U(e){const{sidebar:t,toc:a,children:s,...r}=e,l=t&&t.items.length>0;return(0,d.jsx)(i.A,{...r,children:(0,d.jsx)("div",{className:"container margin-vert--lg",children:(0,d.jsxs)("div",{className:"row",children:[(0,d.jsx)(O,{sidebar:t}),(0,d.jsx)("main",{className:(0,n.A)("col",{"col--7":l,"col--9 col--offset-1":!l}),children:s}),a&&(0,d.jsx)("div",{className:"col col--2",children:a})]})})})}},9158:(e,t,a)=>{a.r(t),a.d(t,{default:()=>b});a(6540);var s=a(4164),n=a(1312);const i=()=>(0,n.T)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});var r=a(5500),l=a(7559),o=a(8027),c=a(6133),m=a(1107);const d={tag:"tag_Nnez"};var u=a(4848);function g({letterEntry:e}){return(0,u.jsxs)("article",{children:[(0,u.jsx)(m.A,{as:"h2",id:e.letter,children:e.letter}),(0,u.jsx)("ul",{className:"padding--none",children:e.tags.map((e=>(0,u.jsx)("li",{className:d.tag,children:(0,u.jsx)(c.A,{...e})},e.permalink)))}),(0,u.jsx)("hr",{})]})}function h({tags:e}){const t=function(e){const t={};return Object.values(e).forEach((e=>{const a=function(e){return e[0].toUpperCase()}(e.label);t[a]??=[],t[a].push(e)})),Object.entries(t).sort((([e],[t])=>e.localeCompare(t))).map((([e,t])=>({letter:e,tags:t.sort(((e,t)=>e.label.localeCompare(t.label)))})))}(e);return(0,u.jsx)("section",{className:"margin-vert--lg",children:t.map((e=>(0,u.jsx)(g,{letterEntry:e},e.letter)))})}var p=a(1463);function b({tags:e,sidebar:t}){const a=i();return(0,u.jsxs)(r.e3,{className:(0,s.A)(l.G.wrapper.blogPages,l.G.page.blogTagsListPage),children:[(0,u.jsx)(r.be,{title:a}),(0,u.jsx)(p.A,{tag:"blog_tags_list"}),(0,u.jsxs)(o.A,{sidebar:t,children:[(0,u.jsx)(m.A,{as:"h1",children:a}),(0,u.jsx)(h,{tags:e})]})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/01a85c17.9618aedf.js b/docs/assets/js/01a85c17.9618aedf.js new file mode 100644 index 00000000..d1f89fa3 --- /dev/null +++ b/docs/assets/js/01a85c17.9618aedf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8209],{4096:(e,t,a)=>{a.d(t,{in:()=>c,OU:()=>P,Ki:()=>y,kJ:()=>b,x:()=>l,e7:()=>m,J_:()=>f,Gx:()=>A});var s=a(6540),n=a(9532),i=a(6803),r=a(4848);function l(){const e=(0,i.A)(),t=e?.data?.blogMetadata;if(!t)throw new Error("useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context");return t}const o=s.createContext(null);function c({children:e,content:t,isBlogPostPage:a=!1}){const n=function({content:e,isBlogPostPage:t}){return(0,s.useMemo)(()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,toc:e.toc,isBlogPostPage:t}),[e,t])}({content:t,isBlogPostPage:a});return(0,r.jsx)(o.Provider,{value:n,children:e})}function m(){const e=(0,s.useContext)(o);if(null===e)throw new n.dV("BlogPostProvider");return e}var d=a(6025),u=a(4586);const g=e=>new Date(e).toISOString();function h(e){const t=e.map(x);return{author:1===t.length?t[0]:t}}function p(e,t,a){return e?{image:j({imageUrl:t(e,{absolute:!0}),caption:`title image for the blog post: ${a}`})}:{}}function b(e){const{siteConfig:t}=(0,u.A)(),{withBaseUrl:a}=(0,d.hH)(),{metadata:{blogDescription:s,blogTitle:n,permalink:i}}=e,r=`${t.url}${i}`;return{"@context":"https://schema.org","@type":"Blog","@id":r,mainEntityOfPage:r,headline:n,description:s,blogPost:e.items.map(e=>function(e,t,a){const{assets:s,frontMatter:n,metadata:i}=e,{date:r,title:l,description:o,lastUpdatedAt:c}=i,m=s.image??n.image,d=n.keywords??[],u=`${t.url}${i.permalink}`,b=c?g(c):void 0;return{"@type":"BlogPosting","@id":u,mainEntityOfPage:u,url:u,headline:l,name:l,description:o,datePublished:r,...b?{dateModified:b}:{},...h(i.authors),...p(m,a,l),...d?{keywords:d}:{}}}(e.content,t,a))}}function f(){const e=l(),{assets:t,metadata:a}=m(),{siteConfig:s}=(0,u.A)(),{withBaseUrl:n}=(0,d.hH)(),{date:i,title:r,description:o,frontMatter:c,lastUpdatedAt:b}=a,f=t.image??c.image,x=c.keywords??[],j=b?g(b):void 0,N=`${s.url}${a.permalink}`;return{"@context":"https://schema.org","@type":"BlogPosting","@id":N,mainEntityOfPage:N,url:N,headline:r,name:r,description:o,datePublished:i,...j?{dateModified:j}:{},...h(a.authors),...p(f,n,r),...x?{keywords:x}:{},isPartOf:{"@type":"Blog","@id":`${s.url}${e.blogBasePath}`,name:e.blogTitle}}}function x(e){return{"@type":"Person",...e.name?{name:e.name}:{},...e.title?{description:e.title}:{},...e.url?{url:e.url}:{},...e.email?{email:e.email}:{},...e.imageURL?{image:e.imageURL}:{}}}function j({imageUrl:e,caption:t}){return{"@type":"ImageObject","@id":e,url:e,contentUrl:e,caption:t}}var N=a(6347),v=a(8774),C=a(1682),k=a(9169);function A(e){const{pathname:t}=(0,N.zy)();return(0,s.useMemo)(()=>e.filter(e=>function(e,t){return!(e.unlisted&&!(0,k.ys)(e.permalink,t))}(e,t)),[e,t])}function y(e){const t=(0,C.$z)(e,e=>`${new Date(e.date).getFullYear()}`),a=Object.entries(t);return a.reverse(),a}function P({items:e,ulClassName:t,liClassName:a,linkClassName:s,linkActiveClassName:n}){return(0,r.jsx)("ul",{className:t,children:e.map(e=>(0,r.jsx)("li",{className:a,children:(0,r.jsx)(v.A,{isNavLink:!0,to:e.permalink,className:s,activeClassName:n,children:e.title})},e.permalink))})}},6133:(e,t,a)=>{a.d(t,{A:()=>l});a(6540);var s=a(4164),n=a(8774);const i={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var r=a(4848);function l({permalink:e,label:t,count:a,description:l}){return(0,r.jsxs)(n.A,{rel:"tag",href:e,title:l,className:(0,s.A)(i.tag,a?i.tagWithCount:i.tagRegular),children:[t,a&&(0,r.jsx)("span",{children:a})]})}},8027:(e,t,a)=>{a.d(t,{A:()=>U});var s=a(6540),n=a(4164),i=a(1656),r=a(4581),l=a(1312),o=a(4096),c=a(6342),m=a(1107),d=a(4848);function u({year:e,yearGroupHeadingClassName:t,children:a}){return(0,d.jsxs)("div",{role:"group",children:[(0,d.jsx)(m.A,{as:"h3",className:t,children:e}),a]})}function g({items:e,yearGroupHeadingClassName:t,ListComponent:a}){if((0,c.p)().blog.sidebar.groupByYear){const s=(0,o.Ki)(e);return(0,d.jsx)(d.Fragment,{children:s.map(([e,s])=>(0,d.jsx)(u,{year:e,yearGroupHeadingClassName:t,children:(0,d.jsx)(a,{items:s})},e))})}return(0,d.jsx)(a,{items:e})}const h=(0,s.memo)(g),p="sidebar_re4s",b="sidebarItemTitle_pO2u",f="sidebarItemList_Yudw",x="sidebarItem__DBe",j="sidebarItemLink_mo7H",N="sidebarItemLinkActive_I1ZP",v="yearGroupHeading_rMGB",C=({items:e})=>(0,d.jsx)(o.OU,{items:e,ulClassName:(0,n.A)(f,"clean-list"),liClassName:x,linkClassName:j,linkActiveClassName:N});function k({sidebar:e}){const t=(0,o.Gx)(e.items);return(0,d.jsx)("aside",{className:"col col--3",children:(0,d.jsxs)("nav",{className:(0,n.A)(p,"thin-scrollbar"),"aria-label":(0,l.T)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"}),children:[(0,d.jsx)("div",{className:(0,n.A)(b,"margin-bottom--md"),children:e.title}),(0,d.jsx)(h,{items:t,ListComponent:C,yearGroupHeadingClassName:v})]})})}const A=(0,s.memo)(k);var y=a(5600);const P="yearGroupHeading_QT03",_=({items:e})=>(0,d.jsx)(o.OU,{items:e,ulClassName:"menu__list",liClassName:"menu__list-item",linkClassName:"menu__link",linkActiveClassName:"menu__link--active"});function w({sidebar:e}){const t=(0,o.Gx)(e.items);return(0,d.jsx)(h,{items:t,ListComponent:_,yearGroupHeadingClassName:P})}function B(e){return(0,d.jsx)(y.GX,{component:w,props:e})}const G=(0,s.memo)(B);function O({sidebar:e}){const t=(0,r.l)();return e?.items.length?"mobile"===t?(0,d.jsx)(G,{sidebar:e}):(0,d.jsx)(A,{sidebar:e}):null}function U(e){const{sidebar:t,toc:a,children:s,...r}=e,l=t&&t.items.length>0;return(0,d.jsx)(i.A,{...r,children:(0,d.jsx)("div",{className:"container margin-vert--lg",children:(0,d.jsxs)("div",{className:"row",children:[(0,d.jsx)(O,{sidebar:t}),(0,d.jsx)("main",{className:(0,n.A)("col",{"col--7":l,"col--9 col--offset-1":!l}),children:s}),a&&(0,d.jsx)("div",{className:"col col--2",children:a})]})})})}},9158:(e,t,a)=>{a.r(t),a.d(t,{default:()=>b});a(6540);var s=a(4164),n=a(1312);const i=()=>(0,n.T)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});var r=a(5500),l=a(7559),o=a(8027),c=a(6133),m=a(1107);const d={tag:"tag_Nnez"};var u=a(4848);function g({letterEntry:e}){return(0,u.jsxs)("article",{children:[(0,u.jsx)(m.A,{as:"h2",id:e.letter,children:e.letter}),(0,u.jsx)("ul",{className:"padding--none",children:e.tags.map(e=>(0,u.jsx)("li",{className:d.tag,children:(0,u.jsx)(c.A,{...e})},e.permalink))}),(0,u.jsx)("hr",{})]})}function h({tags:e}){const t=function(e){const t={};return Object.values(e).forEach(e=>{const a=function(e){return e[0].toUpperCase()}(e.label);t[a]??=[],t[a].push(e)}),Object.entries(t).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>({letter:e,tags:t.sort((e,t)=>e.label.localeCompare(t.label))}))}(e);return(0,u.jsx)("section",{className:"margin-vert--lg",children:t.map(e=>(0,u.jsx)(g,{letterEntry:e},e.letter))})}var p=a(1463);function b({tags:e,sidebar:t}){const a=i();return(0,u.jsxs)(r.e3,{className:(0,s.A)(l.G.wrapper.blogPages,l.G.page.blogTagsListPage),children:[(0,u.jsx)(r.be,{title:a}),(0,u.jsx)(p.A,{tag:"blog_tags_list"}),(0,u.jsxs)(o.A,{sidebar:t,children:[(0,u.jsx)(m.A,{as:"h1",children:a}),(0,u.jsx)(h,{tags:e})]})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/0413d9af.cb9ba41f.js b/docs/assets/js/0413d9af.aecac3d5.js similarity index 56% rename from docs/assets/js/0413d9af.cb9ba41f.js rename to docs/assets/js/0413d9af.aecac3d5.js index 6070c9ad..88711431 100644 --- a/docs/assets/js/0413d9af.cb9ba41f.js +++ b/docs/assets/js/0413d9af.aecac3d5.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9919],{7114:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>o});const s=JSON.parse('{"id":"sdks/python/v1.0.0/grpc_feature_client","title":"GRPC Feature client","description":"PyPI version","source":"@site/docs/sdks/python/v1.0.0/grpc_feature_client.md","sourceDirName":"sdks/python/v1.0.0","slug":"/sdks/python/v1.0.0/grpc_feature_client","permalink":"/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/sdks/python/v1.0.0/grpc_feature_client.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"GRPC Feature client","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"v1.0.0","permalink":"/BharatMLStack/category/v100"},"next":{"title":"Spark client","permalink":"/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client"}}');var i=t(4848),r=t(8453);const a={title:"GRPC Feature client",sidebar_position:1},l="GRPC Feature Client",c={},o=[{value:"Installation",id:"installation",level:2},{value:"Dependencies",id:"dependencies",level:2},{value:"Features",id:"features",level:2},{value:"Quick Start",id:"quick-start",level:2},{value:"API Reference",id:"api-reference",level:2},{value:"GRPCFeatureClient",id:"grpcfeatureclient",level:3},{value:"GRPCClientConfig",id:"grpcclientconfig",level:3},{value:"Usage Examples",id:"usage-examples",level:2},{value:"Persisting Features",id:"persisting-features",level:3},{value:"Retrieving Features",id:"retrieving-features",level:3},{value:"With Context Management",id:"with-context-management",level:3},{value:"When to Use",id:"when-to-use",level:2},{value:"Related Packages",id:"related-packages",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"grpc-feature-client",children:"GRPC Feature Client"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://badge.fury.io/py/grpc_feature_client",children:(0,i.jsx)(n.img,{src:"https://img.shields.io/pypi/v/grpc_feature_client?label=pypi-package&color=light%20green",alt:"PyPI version"})}),"\n",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/actions/workflows/py-sdk.yml",children:(0,i.jsx)(n.img,{src:"https://github.com/Meesho/BharatMLStack/actions/workflows/py-sdk.yml/badge.svg",alt:"Build Status"})}),"\n",(0,i.jsx)(n.a,{href:"https://www.python.org/downloads/",children:(0,i.jsx)(n.img,{src:"https://img.shields.io/badge/python-3.7+-blue.svg",alt:"Python 3.7+"})}),"\n",(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:(0,i.jsx)(n.img,{src:"https://img.shields.io/badge/Discord-Join%20Chat-7289da?style=flat&logo=discord&logoColor=white",alt:"Discord"})}),"\n",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:(0,i.jsx)(n.img,{src:"https://img.shields.io/badge/License-BharatMLStack%20BSL%201.1-blue.svg",alt:"License"})})]}),"\n",(0,i.jsx)(n.p,{children:"High-performance gRPC client for BharatML Stack real-time feature operations with direct API access."}),"\n",(0,i.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"pip install grpc_feature_client\n"})}),"\n",(0,i.jsx)(n.h2,{id:"dependencies",children:"Dependencies"}),"\n",(0,i.jsx)(n.p,{children:"This package depends on:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.a,{href:"https://pypi.org/project/bharatml_commons/",children:"bharatml_commons"})}),": Common utilities and protobuf definitions"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"grpcio>=1.50.0"}),": gRPC framework"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"grpcio-tools>=1.50.0"}),": gRPC tools for protobuf"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"features",children:"Features"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Direct gRPC API"}),": persist, retrieve, retrieveDecoded operations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Go SDK Compatible"}),": Same authentication and API semantics"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Batch Processing"}),": Automatic batching with parallel execution"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Real-time Focus"}),": Low-latency feature persistence and retrieval"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Context Management"}),": Timeout and metadata handling"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Connection Pooling"}),": Efficient connection management"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"quick-start",children:"Quick Start"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'from grpc_feature_client import GRPCFeatureClient, GRPCClientConfig\n\n# Configure for real-time operations\nconfig = GRPCClientConfig(\n server_address="localhost:50051",\n job_id="realtime-service",\n job_token="api-token"\n)\n\nclient = GRPCFeatureClient(config)\n\n# Direct API operations\nresult = client.persist_features(entity_label, keys_schema, feature_groups, data)\nfeatures = client.retrieve_decoded_features(entity_label, feature_groups, keys, entity_keys)\n'})}),"\n",(0,i.jsx)(n.h2,{id:"api-reference",children:"API Reference"}),"\n",(0,i.jsx)(n.h3,{id:"grpcfeatureclient",children:"GRPCFeatureClient"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:"class GRPCFeatureClient:\n def __init__(self, config: GRPCClientConfig)\n \n def persist_features(\n self,\n entity_label: str,\n keys_schema: List[str],\n feature_group_schemas: List[Dict[str, Any]],\n data_rows: List[Dict[str, Any]],\n timeout: Optional[float] = None\n ) -> Dict[str, Any]\n \n def retrieve_features(\n self,\n entity_label: str,\n feature_groups: List[Dict[str, Any]],\n keys_schema: List[str],\n entity_keys: List[List[str]],\n timeout: Optional[float] = None\n ) -> Dict[str, Any]\n \n def retrieve_decoded_features(\n self,\n entity_label: str,\n feature_groups: List[Dict[str, Any]],\n keys_schema: List[str],\n entity_keys: List[List[str]],\n timeout: Optional[float] = None\n ) -> Dict[str, Any]\n"})}),"\n",(0,i.jsx)(n.h3,{id:"grpcclientconfig",children:"GRPCClientConfig"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:"class GRPCClientConfig:\n def __init__(\n self,\n server_address: str,\n job_id: str,\n job_token: str,\n use_tls: bool = False,\n timeout_seconds: float = 30.0,\n metadata: Dict[str, str] = None,\n max_receive_message_length: int = 4 * 1024 * 1024,\n max_send_message_length: int = 4 * 1024 * 1024\n )\n"})}),"\n",(0,i.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,i.jsx)(n.h3,{id:"persisting-features",children:"Persisting Features"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'from grpc_feature_client import GRPCFeatureClient, GRPCClientConfig\n\nconfig = GRPCClientConfig(\n server_address="feature-store.example.com:50051",\n job_id="predator",\n job_token="api-token"\n)\n\nclient = GRPCFeatureClient(config)\n\n# Persist real-time features\nresult = client.persist_features(\n entity_label="user_interaction",\n keys_schema=["user_id", "session_id"],\n feature_group_schemas=[{\n "label": "realtime_features",\n "feature_labels": ["click_count", "page_views"]\n }],\n data_rows=[{\n "user_id": "u123",\n "session_id": "s456",\n "click_count": 5,\n "page_views": 3\n }]\n)\n\nprint(f"Persist result: {result}")\n'})}),"\n",(0,i.jsx)(n.h3,{id:"retrieving-features",children:"Retrieving Features"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'# Retrieve features for ML model inference\nfeatures = client.retrieve_decoded_features(\n entity_label="user_interaction",\n feature_groups=[{\n "label": "user_features",\n "feature_labels": ["age", "location"]\n }],\n keys_schema=["user_id"],\n entity_keys=[["u123"], ["u456"]]\n)\n\nprint(f"Retrieved features: {features}")\n'})}),"\n",(0,i.jsx)(n.h3,{id:"with-context-management",children:"With Context Management"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:"# Use client with automatic cleanup\nwith GRPCFeatureClient(config) as client:\n result = client.persist_features(...)\n features = client.retrieve_decoded_features(...)\n# Connection automatically closed\n"})}),"\n",(0,i.jsx)(n.h2,{id:"when-to-use",children:"When to Use"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Use grpc_feature_client for:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\ud83d\ude80 ",(0,i.jsx)(n.strong,{children:"Real-time Operations"}),": Direct persist/retrieve operations"]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udd0d ",(0,i.jsx)(n.strong,{children:"Interactive Queries"}),": Low-latency feature lookups"]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83c\udfaf ",(0,i.jsx)(n.strong,{children:"API Integration"}),": Service-to-service communication"]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udca8 ",(0,i.jsx)(n.strong,{children:"Single Records"}),": Persisting individual feature records"]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udd04 ",(0,i.jsx)(n.strong,{children:"Model Serving"}),": Feature retrieval for online inference"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Use spark_feature_push_client for:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\ud83d\udd04 ",(0,i.jsx)(n.strong,{children:"Batch ETL Pipelines"}),": Scheduled feature computation and publishing"]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udcca ",(0,i.jsx)(n.strong,{children:"Historical Data Backfill"}),": Loading historical features into online store"]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83c\udfd7\ufe0f ",(0,i.jsx)(n.strong,{children:"Data Engineering"}),": Spark-based feature transformations"]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udcc8 ",(0,i.jsx)(n.strong,{children:"Large Scale Processing"}),": Processing millions of records efficiently"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"related-packages",children:"Related Packages"}),"\n",(0,i.jsx)(n.p,{children:"This package is part of the BharatML Stack ecosystem:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.a,{href:"https://pypi.org/project/bharatml_commons/",children:"bharatml_commons"})}),": Common utilities and protobuf definitions (required dependency)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.a,{href:"https://pypi.org/project/spark_feature_push_client/",children:"spark_feature_push_client"})}),": Spark-based data pipeline client"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,i.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,i.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\ud83d\udcac ",(0,i.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,i.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,i.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,i.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,i.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>l});var s=t(6540);const i={},r=s.createContext(i);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9919],{7114:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>o});const s=JSON.parse('{"id":"sdks/python/v1.0.0/grpc_feature_client","title":"GRPC Feature client","description":"PyPI version","source":"@site/docs/sdks/python/v1.0.0/grpc_feature_client.md","sourceDirName":"sdks/python/v1.0.0","slug":"/sdks/python/v1.0.0/grpc_feature_client","permalink":"/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/sdks/python/v1.0.0/grpc_feature_client.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"GRPC Feature client","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"v1.0.0","permalink":"/BharatMLStack/category/v100"},"next":{"title":"Spark client","permalink":"/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client"}}');var i=t(4848),r=t(8453);const a={title:"GRPC Feature client",sidebar_position:1},l="GRPC Feature Client",c={},o=[{value:"Installation",id:"installation",level:2},{value:"Dependencies",id:"dependencies",level:2},{value:"Features",id:"features",level:2},{value:"Quick Start",id:"quick-start",level:2},{value:"API Reference",id:"api-reference",level:2},{value:"GRPCFeatureClient",id:"grpcfeatureclient",level:3},{value:"GRPCClientConfig",id:"grpcclientconfig",level:3},{value:"Usage Examples",id:"usage-examples",level:2},{value:"Persisting Features",id:"persisting-features",level:3},{value:"Retrieving Features",id:"retrieving-features",level:3},{value:"With Context Management",id:"with-context-management",level:3},{value:"When to Use",id:"when-to-use",level:2},{value:"Related Packages",id:"related-packages",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"grpc-feature-client",children:"GRPC Feature Client"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://badge.fury.io/py/grpc_feature_client",children:(0,i.jsx)(n.img,{src:"https://img.shields.io/pypi/v/grpc_feature_client?label=pypi-package&color=light%20green",alt:"PyPI version"})}),"\n",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/actions/workflows/py-sdk.yml",children:(0,i.jsx)(n.img,{src:"https://github.com/Meesho/BharatMLStack/actions/workflows/py-sdk.yml/badge.svg",alt:"Build Status"})}),"\n",(0,i.jsx)(n.a,{href:"https://www.python.org/downloads/",children:(0,i.jsx)(n.img,{src:"https://img.shields.io/badge/python-3.7+-blue.svg",alt:"Python 3.7+"})}),"\n",(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:(0,i.jsx)(n.img,{src:"https://img.shields.io/badge/Discord-Join%20Chat-7289da?style=flat&logo=discord&logoColor=white",alt:"Discord"})}),"\n",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:(0,i.jsx)(n.img,{src:"https://img.shields.io/badge/License-BharatMLStack%20BSL%201.1-blue.svg",alt:"License"})})]}),"\n",(0,i.jsx)(n.p,{children:"High-performance gRPC client for BharatML Stack real-time feature operations with direct API access."}),"\n",(0,i.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"pip install grpc_feature_client\n"})}),"\n",(0,i.jsx)(n.h2,{id:"dependencies",children:"Dependencies"}),"\n",(0,i.jsx)(n.p,{children:"This package depends on:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.a,{href:"https://pypi.org/project/bharatml_commons/",children:"bharatml_commons"})}),": Common utilities and protobuf definitions"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"grpcio>=1.50.0"}),": gRPC framework"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"grpcio-tools>=1.50.0"}),": gRPC tools for protobuf"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"features",children:"Features"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Direct gRPC API"}),": persist, retrieve, retrieveDecoded operations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Go SDK Compatible"}),": Same authentication and API semantics"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Batch Processing"}),": Automatic batching with parallel execution"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Real-time Focus"}),": Low-latency feature persistence and retrieval"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Context Management"}),": Timeout and metadata handling"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Connection Pooling"}),": Efficient connection management"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"quick-start",children:"Quick Start"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'from grpc_feature_client import GRPCFeatureClient, GRPCClientConfig\n\n# Configure for real-time operations\nconfig = GRPCClientConfig(\n server_address="localhost:50051",\n job_id="realtime-service",\n job_token="api-token"\n)\n\nclient = GRPCFeatureClient(config)\n\n# Direct API operations\nresult = client.persist_features(entity_label, keys_schema, feature_groups, data)\nfeatures = client.retrieve_decoded_features(entity_label, feature_groups, keys, entity_keys)\n'})}),"\n",(0,i.jsx)(n.h2,{id:"api-reference",children:"API Reference"}),"\n",(0,i.jsx)(n.h3,{id:"grpcfeatureclient",children:"GRPCFeatureClient"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:"class GRPCFeatureClient:\n def __init__(self, config: GRPCClientConfig)\n \n def persist_features(\n self,\n entity_label: str,\n keys_schema: List[str],\n feature_group_schemas: List[Dict[str, Any]],\n data_rows: List[Dict[str, Any]],\n timeout: Optional[float] = None\n ) -> Dict[str, Any]\n \n def retrieve_features(\n self,\n entity_label: str,\n feature_groups: List[Dict[str, Any]],\n keys_schema: List[str],\n entity_keys: List[List[str]],\n timeout: Optional[float] = None\n ) -> Dict[str, Any]\n \n def retrieve_decoded_features(\n self,\n entity_label: str,\n feature_groups: List[Dict[str, Any]],\n keys_schema: List[str],\n entity_keys: List[List[str]],\n timeout: Optional[float] = None\n ) -> Dict[str, Any]\n"})}),"\n",(0,i.jsx)(n.h3,{id:"grpcclientconfig",children:"GRPCClientConfig"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:"class GRPCClientConfig:\n def __init__(\n self,\n server_address: str,\n job_id: str,\n job_token: str,\n use_tls: bool = False,\n timeout_seconds: float = 30.0,\n metadata: Dict[str, str] = None,\n max_receive_message_length: int = 4 * 1024 * 1024,\n max_send_message_length: int = 4 * 1024 * 1024\n )\n"})}),"\n",(0,i.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,i.jsx)(n.h3,{id:"persisting-features",children:"Persisting Features"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'from grpc_feature_client import GRPCFeatureClient, GRPCClientConfig\n\nconfig = GRPCClientConfig(\n server_address="feature-store.example.com:50051",\n job_id="predator-service",\n job_token="api-token"\n)\n\nclient = GRPCFeatureClient(config)\n\n# Persist real-time features\nresult = client.persist_features(\n entity_label="user_interaction",\n keys_schema=["user_id", "session_id"],\n feature_group_schemas=[{\n "label": "realtime_features",\n "feature_labels": ["click_count", "page_views"]\n }],\n data_rows=[{\n "user_id": "u123",\n "session_id": "s456",\n "click_count": 5,\n "page_views": 3\n }]\n)\n\nprint(f"Persist result: {result}")\n'})}),"\n",(0,i.jsx)(n.h3,{id:"retrieving-features",children:"Retrieving Features"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'# Retrieve features for ML model inference\nfeatures = client.retrieve_decoded_features(\n entity_label="user_interaction",\n feature_groups=[{\n "label": "user_features",\n "feature_labels": ["age", "location"]\n }],\n keys_schema=["user_id"],\n entity_keys=[["u123"], ["u456"]]\n)\n\nprint(f"Retrieved features: {features}")\n'})}),"\n",(0,i.jsx)(n.h3,{id:"with-context-management",children:"With Context Management"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:"# Use client with automatic cleanup\nwith GRPCFeatureClient(config) as client:\n result = client.persist_features(...)\n features = client.retrieve_decoded_features(...)\n# Connection automatically closed\n"})}),"\n",(0,i.jsx)(n.h2,{id:"when-to-use",children:"When to Use"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Use grpc_feature_client for:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\ud83d\ude80 ",(0,i.jsx)(n.strong,{children:"Real-time Operations"}),": Direct persist/retrieve operations"]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udd0d ",(0,i.jsx)(n.strong,{children:"Interactive Queries"}),": Low-latency feature lookups"]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83c\udfaf ",(0,i.jsx)(n.strong,{children:"API Integration"}),": Service-to-service communication"]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udca8 ",(0,i.jsx)(n.strong,{children:"Single Records"}),": Persisting individual feature records"]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udd04 ",(0,i.jsx)(n.strong,{children:"Model Serving"}),": Feature retrieval for online inference"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Use spark_feature_push_client for:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\ud83d\udd04 ",(0,i.jsx)(n.strong,{children:"Batch ETL Pipelines"}),": Scheduled feature computation and publishing"]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udcca ",(0,i.jsx)(n.strong,{children:"Historical Data Backfill"}),": Loading historical features into online store"]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83c\udfd7\ufe0f ",(0,i.jsx)(n.strong,{children:"Data Engineering"}),": Spark-based feature transformations"]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udcc8 ",(0,i.jsx)(n.strong,{children:"Large Scale Processing"}),": Processing millions of records efficiently"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"related-packages",children:"Related Packages"}),"\n",(0,i.jsx)(n.p,{children:"This package is part of the BharatML Stack ecosystem:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.a,{href:"https://pypi.org/project/bharatml_commons/",children:"bharatml_commons"})}),": Common utilities and protobuf definitions (required dependency)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.a,{href:"https://pypi.org/project/spark_feature_push_client/",children:"spark_feature_push_client"})}),": Spark-based data pipeline client"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,i.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,i.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\ud83d\udcac ",(0,i.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,i.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,i.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,i.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,i.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>l});var s=t(6540);const i={},r=s.createContext(i);function a(e){const n=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/08daf6b6.852abb6b.js b/docs/assets/js/08daf6b6.852abb6b.js new file mode 100644 index 00000000..d12c0df2 --- /dev/null +++ b/docs/assets/js/08daf6b6.852abb6b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1686],{848:a=>{a.exports=JSON.parse('{"tag":{"label":"model-inference","permalink":"/BharatMLStack/blog/tags/model-inference","allTagsPath":"/BharatMLStack/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/BharatMLStack/blog/tags/model-inference","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/09dd5be9.9cd209bb.js b/docs/assets/js/09dd5be9.9cd209bb.js deleted file mode 100644 index d07ca928..00000000 --- a/docs/assets/js/09dd5be9.9cd209bb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6273],{1012:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/interaction-store-v0-68167b64c6e462ef2f177f0f86d55bda.png"},3190:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/schema-d699efc400ed0f83bba421c1f55ab211.png"},3518:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/old-batch-arch-bc2cedbc1fed0fc6f08479ba8fe52996.png"},3983:e=>{e.exports=JSON.parse('{"permalink":"/BharatMLStack/blog/post-one","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-one/index.md","source":"@site/blog/bharatmlstack-history/post-one/index.md","title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","description":"BharatMLStack","date":"2022-11-15T00:00:00.000Z","tags":[{"inline":true,"label":"online-feature-store","permalink":"/BharatMLStack/blog/tags/online-feature-store"},{"inline":true,"label":"interaction-store","permalink":"/BharatMLStack/blog/tags/interaction-store"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"}],"readingTime":10.25,"hasTruncateMarker":false,"authors":[{"name":"Adarsha Das","title":"Senior Architect @ Meesho","url":"https://github.com/a0d00kc","imageURL":"https://github.com/a0d00kc.png","key":"adarsha","page":null},{"name":"Aditya Kumar","title":"SDE-III @ Meesho","url":"https://github.com/Adit2607","imageURL":"https://github.com/Adit2607.png","key":"aditya","page":null},{"name":"Bhawani Singh","title":"SDE-IV @ Meesho","url":"https://github.com/singh-bhawani","imageURL":"https://github.com/singh-bhawani.png","key":"bhawani","page":null},{"name":"Jigar Dave","title":"SDE-IV @ Meesho","url":"https://github.com/jigarpatel26","imageURL":"https://github.com/jigarpatel26.png","key":"jigar","page":null}],"frontMatter":{"slug":"post-one","title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","authors":["adarsha","aditya","bhawani","jigar"],"date":"2022-11-15T00:00:00.000Z","tags":["online-feature-store","interaction-store","mlplatform","meesho"]},"unlisted":false}')},5728:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/online-feature-store-v0-86ec0010947ae24621f39ebd0d1729ca.png"},7131:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/first-gen-arch-7c0b286810aecb7eff42b48f51caee1f.png"},8453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>o});var t=i(6540);const s={},r=t.createContext(s);function a(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(r.Provider,{value:n},e.children)}},8831:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>c,frontMatter:()=>a,metadata:()=>t,toc:()=>d});var t=i(3983),s=i(4848),r=i(8453);const a={slug:"post-one",title:"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)",authors:["adarsha","aditya","bhawani","jigar"],date:new Date("2022-11-15T00:00:00.000Z"),tags:["online-feature-store","interaction-store","mlplatform","meesho"]},o=void 0,l={authorsImageUrls:[void 0,void 0,void 0,void 0]},d=[{value:"The Genesis: How a Friday Night Roast Sparked Meesho\u2019s ML Platform",id:"the-genesis-how-a-friday-night-roast-sparked-meeshos-ml-platform",level:2},{value:"The Turning Point: From Batch to Real-Time",id:"the-turning-point-from-batch-to-real-time",level:2},{value:"First Generation Design",id:"first-generation-design",level:2},{value:"1. IOP Framework: A Real-Time DAG Executor",id:"1-iop-framework-a-real-time-dag-executor",level:3},{value:"2. Online Feature Store - 0th Version",id:"2-online-feature-store---0th-version",level:3},{value:"3. Interaction Store - 0th Version",id:"3-interaction-store---0th-version",level:3},{value:"Building the Online Feature Store - 0th Version",id:"building-the-online-feature-store---0th-version",level:2},{value:"Choosing the Right Tech Stack",id:"choosing-the-right-tech-stack",level:3},{value:"Streamlining the Data Flow",id:"streamlining-the-data-flow",level:3},{value:"The Challenges: Data Format and Storage",id:"the-challenges-data-format-and-storage",level:2},{value:"Feature Consistency",id:"feature-consistency",level:3},{value:"TTL Granularity",id:"ttl-granularity",level:3},{value:"Extensibility Across Databases",id:"extensibility-across-databases",level:3},{value:"Overcoming Technical Constraints",id:"overcoming-technical-constraints",level:2},{value:"The Solution: Schema Separation",id:"the-solution-schema-separation",level:2},{value:"Tracking Changes in Feature Groups",id:"tracking-changes-in-feature-groups",level:2},{value:"Common Real-World Scenarios:",id:"common-real-world-scenarios",level:3},{value:"The Solution: Schema Versioning",id:"the-solution-schema-versioning",level:2},{value:"Backward Compatibility",id:"backward-compatibility",level:3},{value:"Partial Availability Handling",id:"partial-availability-handling",level:3},{value:"Safe Writes Without Pipeline Pauses",id:"safe-writes-without-pipeline-pauses",level:3},{value:"Interaction Store - 0th Version",id:"interaction-store---0th-version",level:2},{value:"Event Ingestion",id:"event-ingestion",level:2},{value:"Storage Design",id:"storage-design",level:2},{value:"Why Redis?",id:"why-redis",level:3},{value:"Storage Structure",id:"storage-structure",level:3},{value:"Built-in Guardrails",id:"built-in-guardrails",level:3},{value:"Conclusion: Laying the Foundation for Real-Time ML",id:"conclusion-laying-the-foundation-for-real-time-ml",level:2}];function h(e){const n={a:"a",br:"br",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"BharatMLStack",src:i(9930).A+"",width:"1472",height:"892"})}),"\n",(0,s.jsx)(n.h2,{id:"the-genesis-how-a-friday-night-roast-sparked-meeshos-ml-platform",children:"The Genesis: How a Friday Night Roast Sparked Meesho\u2019s ML Platform"}),"\n",(0,s.jsx)(n.p,{children:"It all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting\u2014until one remark hit a little too close to home:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.em,{children:'"Why are we still crunching data for Monthly Active Users (MAU) when the next day it\u2019s all about Daily Active Users (DAU)?"'})}),"\n",(0,s.jsx)(n.p,{children:"The laughter died down, and the question lingered. When we regrouped on Monday\u2014clear-headed and slightly reflective\u2014we decided to dig into the numbers. What they discovered was quite revealing: a large portion of compute resources wasn\u2019t being put to good use.\nMuch of the system\u2019s effort was spent supporting users who weren\u2019t actively engaging, and even for new users, the experience wasn\u2019t optimized to make a meaningful impact."}),"\n",(0,s.jsxs)(n.p,{children:["At the same time, Meesho had just launched a company-wide initiative to reduce costs\u2014and every team had to contribute. This realization sparked the journey that would eventually lead to the ",(0,s.jsx)(n.strong,{children:"Meesho ML Platform"}),", known today as ",(0,s.jsx)(n.strong,{children:"BharatMLStack"}),"."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(3518).A+"",width:"1600",height:"1078"})}),"\n",(0,s.jsx)(n.p,{children:"Before the ML Platform, our recommendation and ranking pipelines followed a batch processing approach:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Data Ingestion"}),": The Data Platform team executed ETL jobs to ingest raw user data\u2014including user profiles, interaction logs, and product impressions\u2014into designated S3 buckets."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Layer 1"}),": Embedding Generation: On the Data Science side, Spark jobs pulled data from multiple S3 sources, cleaned and preprocessed it, and applied matrix factorization to generate user and item embeddings. The processed data and embeddings were then stored back in S3 in a structured format."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Layer 2"}),": Candidate Generation (CG): In this stage, Spark jobs leveraged embeddings and historical interaction data to generate candidate recommendations for users. These candidate lists were subsequently written to S3."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Layer 3"}),": Ranking and Merging \u2013 A final round of processing ranked the generated candidates using ML models, combined different candidate lists, and stored the final ranked recommendations in a caching system."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Serving"}),': A microservice retrieved ranked recommendations from an in-memory data store via exposed APIs, delivering personalized listings across key surfaces such as "For You" and Category Landing Pages (CLP).']}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This approach held up well\u2014until Meesho started seeing a significant surge in traffic."}),"\n",(0,s.jsx)(n.h2,{id:"the-turning-point-from-batch-to-real-time",children:"The Turning Point: From Batch to Real-Time"}),"\n",(0,s.jsxs)(n.p,{children:["At this time, the team was iterating on new ",(0,s.jsx)(n.strong,{children:"Ranker models"}),", and real-time inference seemed like the next logical step. But Rankers needed ",(0,s.jsx)(n.strong,{children:"real-time feature retrieval"}),", which meant an ",(0,s.jsx)(n.strong,{children:"online feature store"})," had to be built first."]}),"\n",(0,s.jsxs)(n.p,{children:["Exploring open-source options led to ",(0,s.jsx)(n.strong,{children:"cost vs. performance trade-offs"}),", but Meesho\u2019s surging traffic meant that ",(0,s.jsx)(n.strong,{children:"latency and stability were non-negotiable"}),". After multiple debates and stakeholder discussions, a bold decision was made:"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.em,{children:"We would build our own feature store."})}),"\n",(0,s.jsxs)(n.p,{children:["Meanwhile, efforts began to bring ",(0,s.jsx)(n.strong,{children:"Candidate Generators (CGs)"})," to real-time. The challenge? ",(0,s.jsx)(n.strong,{children:"Storing and retrieving user interactions quickly enough"})," to power real-time recommendations."]}),"\n",(0,s.jsxs)(n.p,{children:["As the team dove deeper, a new roadblock emerged:",(0,s.jsx)(n.br,{}),"\n","Our ML jobs were orchestrated using ",(0,s.jsx)(n.strong,{children:"Airflow DAGs"}),", giving data scientists flexibility in experimentation. But transitioning to real-time execution threatened this agility. Every change would now require backend engineering support, ",(0,s.jsx)(n.strong,{children:"slowing down iteration cycles"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["That\u2019s when the idea struck:",(0,s.jsx)(n.br,{}),"\n","We needed a ",(0,s.jsx)(n.strong,{children:"framework for real-time DAG execution"}),"\u2014one that preserved the same flexibility as Airflow but worked for ",(0,s.jsx)(n.strong,{children:"streaming data"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This moment shaped the ",(0,s.jsx)(n.strong,{children:"next phase of our journey"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"first-generation-design",children:"First Generation Design"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(7131).A+"",width:"1600",height:"1006"})}),"\n",(0,s.jsx)(n.h1,{id:"laying-the-groundwork-the-first-gen-ml-platform",children:"Laying the Groundwork: The First-Gen ML Platform"}),"\n",(0,s.jsx)(n.p,{children:"To solve these challenges, the team built three foundational components:"}),"\n",(0,s.jsx)(n.h3,{id:"1-iop-framework-a-real-time-dag-executor",children:"1. IOP Framework: A Real-Time DAG Executor"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Reusable Nodes"}),": Each DAG node (e.g., an invocation to a CG service, a ranker, or a filter) had to be implemented only once. After that, it could be reused across any workflow by referencing it in config."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Config-driven Dynamic Graphs"}),": Execution graphs were defined as adjacency lists stored in ",(0,s.jsx)(n.strong,{children:"ZooKeeper"}),", allowing teams to modify the sequence or structure of operations without touching application code."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Plug-and-play CGs"}),": The Candidate Generator interface was preserved, so a single CG node could call any CG service by passing ",(0,s.jsx)(n.code,{children:"cg_name"})," in the request. This drastically reduced the code surface area and improved maintainability."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Production-Grade DAGs"}),": DAGs were designed to execute in ",(0,s.jsx)(n.strong,{children:"low-latency real-time environments"}),", with support for ",(0,s.jsx)(n.strong,{children:"parallel execution, retries, and branching"}),"."]}),"\n"]}),"\n",(0,s.jsx)("u",{children:(0,s.jsx)(n.a,{href:"https://www.meesho.io/blog/rebuilding-meeshos-ranking-platform",children:"More about IOP DAG"})}),"\n",(0,s.jsx)(n.h3,{id:"2-online-feature-store---0th-version",children:"2. Online Feature Store - 0th Version"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Used ",(0,s.jsx)(n.strong,{children:"Cassandra"})," and ",(0,s.jsx)(n.strong,{children:"Redis"})," for low-latency feature serving."]}),"\n",(0,s.jsxs)(n.li,{children:["Maintained feature consistency using ",(0,s.jsx)(n.strong,{children:"Feature Groups"})," with TTL-based expiry."]}),"\n",(0,s.jsxs)(n.li,{children:["A hybrid schema was used: feature keys stored in ",(0,s.jsx)(n.strong,{children:"ZooKeeper"}),", data stored in ",(0,s.jsx)(n.strong,{children:"compact arrays"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"3-interaction-store---0th-version",children:"3. Interaction Store - 0th Version"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Captured real-time user interactions like clicks, orders, and add-to-cart events."}),"\n",(0,s.jsxs)(n.li,{children:["Stored event data in ",(0,s.jsx)(n.strong,{children:"Redis ZSETs (sorted sets)"})," to enable fast lookups for recommendation engines."]}),"\n",(0,s.jsxs)(n.li,{children:["Provided an API to fetch a user's ",(0,s.jsxs)(n.strong,{children:["last ",(0,s.jsx)(n.em,{children:"k"})," interactions"]})," or ",(0,s.jsx)(n.strong,{children:"interactions within a time window"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["With these components in place, ",(0,s.jsx)(n.strong,{children:"real-time ML at Meesho became a reality"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"This was just the beginning."}),"\n",(0,s.jsx)(n.h2,{id:"building-the-online-feature-store---0th-version",children:"Building the Online Feature Store - 0th Version"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt text",src:i(5728).A+"",width:"1574",height:"562"})}),"\n",(0,s.jsx)(n.h3,{id:"choosing-the-right-tech-stack",children:"Choosing the Right Tech Stack"}),"\n",(0,s.jsxs)(n.p,{children:["We spent considerable time evaluating various databases, caches, and communication protocols for our ",(0,s.jsx)(n.strong,{children:"online feature store"}),". After carefully weighing ",(0,s.jsx)(n.strong,{children:"cost, latency, throughput"}),", and ",(0,s.jsx)(n.strong,{children:"operational stability"}),", we settled on a combination of:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Cassandra"})," and ",(0,s.jsx)(n.strong,{children:"Redis"})," for storage"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"gRPC + Proto3"})," as our communication layer"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"streamlining-the-data-flow",children:"Streamlining the Data Flow"}),"\n",(0,s.jsx)(n.p,{children:"To keep things simple in the initial version:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature engineering jobs"})," wrote raw outputs to an ",(0,s.jsx)(n.strong,{children:"S3 bucket"})]}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.strong,{children:"daily feature push job"}),":","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Read from S3"}),"\n",(0,s.jsxs)(n.li,{children:["Grouped related features into ",(0,s.jsx)(n.strong,{children:"Feature Groups"})," (ensuring consistency)"]}),"\n",(0,s.jsxs)(n.li,{children:["Pushed them to ",(0,s.jsx)(n.strong,{children:"Kafka"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"For features requiring frequent updates:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Ad-hoc jobs"})," computed features in higher frequency"]}),"\n",(0,s.jsxs)(n.li,{children:["These jobs pushed to both ",(0,s.jsx)(n.strong,{children:"Kafka"})," and ",(0,s.jsx)(n.strong,{children:"S3"})," (S3 preserved historical data for future model training)"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"the-challenges-data-format-and-storage",children:"The Challenges: Data Format and Storage"}),"\n",(0,s.jsxs)(n.p,{children:["One of the most critical design challenges was how to store feature data ",(0,s.jsx)(n.strong,{children:"efficiently and consistently"}),", especially in databases like ",(0,s.jsx)(n.strong,{children:"Cassandra"})," and ",(0,s.jsx)(n.strong,{children:"Redis"}),", which come with unique storage constraints."]}),"\n",(0,s.jsx)(n.p,{children:"We had to solve for three key requirements:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"feature-consistency",children:"Feature Consistency"}),"\n",(0,s.jsxs)(n.p,{children:["When a feature group contains features like ",(0,s.jsx)(n.code,{children:"order_count_1h"})," and ",(0,s.jsx)(n.code,{children:"click_count_1h"}),", both must reflect the ",(0,s.jsx)(n.strong,{children:"same time window"}),". Inconsistent updates would lead to ",(0,s.jsx)(n.strong,{children:"unreliable model predictions"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"ttl-granularity",children:"TTL Granularity"}),"\n",(0,s.jsxs)(n.p,{children:["Each feature group required an ",(0,s.jsx)(n.strong,{children:"expiry timestamp"}),", so that ",(0,s.jsx)(n.strong,{children:"all features within it expired together"}),"\u2014preserving consistency during reads."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"extensibility-across-databases",children:"Extensibility Across Databases"}),"\n",(0,s.jsxs)(n.p,{children:["We anticipated that infra needs would evolve. To future-proof our system, the data format was designed to be ",(0,s.jsx)(n.strong,{children:"decoupled from DB-specific layouts"}),", enabling portability to systems like ",(0,s.jsx)(n.strong,{children:"ScyllaDB"}),", ",(0,s.jsx)(n.strong,{children:"DynamoDB"}),", ",(0,s.jsx)(n.strong,{children:"HBase"}),", or ",(0,s.jsx)(n.strong,{children:"BigTable"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"overcoming-technical-constraints",children:"Overcoming Technical Constraints"}),"\n",(0,s.jsx)(n.p,{children:'At the time, we were using Cassandra, which not only imposed a soft limit of 75 columns per row, but also exhibited significant performance degradation as the number of columns increased further, particularly in memory constrained machines. Wide rows caused high memory usage during reads, unpredictable latencies due to heavy deserialization overhead, and inefficiencies during compactions and repairs. This ruled out the naive "one column per feature" approach. We needed a format that was compact, minimized the number of columns, and remained efficient and portable across different storage systems.'}),"\n",(0,s.jsx)(n.h2,{id:"the-solution-schema-separation",children:"The Solution: Schema Separation"}),"\n",(0,s.jsx)(n.p,{children:"We introduced the concept of Feature Groups\u2014logical groupings of features that must remain consistent with one another.\nTo represent these groups efficiently, we adopted a layered storage approach:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature Labels (Keys)"})," were stored in ZooKeeper, serving as the schema."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature Values"})," were stored as a comma-separated string array in Cassandra or Redis."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Expiry Timestamp and Schema Version"})," were appended using a semi-colon delimiter at the end of the string."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"feature_1_value,feature_2_value,feature_3_value;expiry_ts\n"})}),"\n",(0,s.jsx)(n.p,{children:"This format allowed:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Consistent writes and reads at the group level"}),"\n",(0,s.jsx)(n.li,{children:"Easy parsing of feature values using the schema lookup from ZooKeeper"}),"\n",(0,s.jsx)(n.li,{children:"Efficient storage with minimal DB column usage"}),"\n",(0,s.jsx)(n.li,{children:"Support for per-group TTLs and schema evolution"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"tracking-changes-in-feature-groups",children:"Tracking Changes in Feature Groups"}),"\n",(0,s.jsx)(n.p,{children:"Feature groups don\u2019t stay static. As models evolve, features get added, renamed, or removed. But schema changes often go live before the data is ready\u2014and stopping ingestion just to wait for everything to align isn't feasible."}),"\n",(0,s.jsx)(n.h3,{id:"common-real-world-scenarios",children:"Common Real-World Scenarios:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"A new feature is added to the schema, but ingestion jobs still use the older schema version."}),"\n",(0,s.jsx)(n.li,{children:"Ongoing writes don\u2019t include the newly added feature, and stopping ingestion would break freshness for existing features."}),"\n",(0,s.jsx)(n.li,{children:"During serving, models request a mix of old and new features, depending on rollout stages."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"the-solution-schema-versioning",children:"The Solution: Schema Versioning"}),"\n",(0,s.jsx)(n.p,{children:"We solved this with versioned feature group schemas, which unlocked several capabilities:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"backward-compatibility",children:"Backward Compatibility"}),"\n","Older ingestion jobs can continue writing using older schema versions. During reads, the system uses the schema version embedded in the value to interpret the data correctly."]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"partial-availability-handling",children:"Partial Availability Handling"}),"\n","During inference, if some features in the request aren\u2019t available (due to rollout delays or missing data), the system serves default values, ensuring the inference call doesn\u2019t fail."]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"safe-writes-without-pipeline-pauses",children:"Safe Writes Without Pipeline Pauses"}),"\n","With schema versioning, we no longer had to stop ingestion pipelines for schema updates. Writes using previous versions can continue safely, and downstream consumers evolve independently.\nThis design gave us the flexibility to move fast without breaking things\u2014preserving data quality, enabling experimentation, and ensuring reliability at scale."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(3190).A+"",width:"1600",height:"599"})}),"\n",(0,s.jsx)(n.h2,{id:"interaction-store---0th-version",children:"Interaction Store - 0th Version"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(1012).A+"",width:"1600",height:"518"})}),"\n",(0,s.jsxs)(n.p,{children:["To power real-time Candidate Generators (CGs), we needed fast access to user behavior signals\u2014like what a user recently clicked, ordered, or added to their cart. These interactions form the basis for many real-time recommendations, such as ",(0,s.jsx)(n.strong,{children:"Similar Products"}),", ",(0,s.jsx)(n.strong,{children:"People Also Viewed"}),", or ",(0,s.jsx)(n.strong,{children:"Recently Ordered Again"}),".\nFor the ",(0,s.jsx)(n.strong,{children:"0th version"})," of the Interaction Store, we focused on a design that was ",(0,s.jsx)(n.strong,{children:"simple, fast, and reliable"})," \u2014 optimized for high-throughput ingestion and low-latency lookups."]}),"\n",(0,s.jsx)(n.h2,{id:"event-ingestion",children:"Event Ingestion"}),"\n",(0,s.jsx)(n.p,{children:"We instrumented our backend services to emit key user interaction events to Kafka in real time. These included:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Click"}),"\n",(0,s.jsx)(n.li,{children:"Order"}),"\n",(0,s.jsx)(n.li,{children:"Add to Cart"}),"\n",(0,s.jsx)(n.li,{children:"Wishlist"}),"\n",(0,s.jsx)(n.li,{children:"Share"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Each event carried essential metadata:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"userId \u2014 uniquely identifies the user"}),"\n",(0,s.jsx)(n.li,{children:"productId \u2014 the item being interacted with"}),"\n",(0,s.jsx)(n.li,{children:"timestamp \u2014 the moment the interaction occurred"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This decoupled the interaction logging from storage, allowing ingestion and consumption to scale independently."}),"\n",(0,s.jsx)(n.h2,{id:"storage-design",children:"Storage Design"}),"\n",(0,s.jsx)(n.p,{children:"To store these events, we built Kafka consumers that processed the incoming streams and wrote the data into Redis, using sorted sets (ZSETs) as the primary data structure."}),"\n",(0,s.jsx)(n.h3,{id:"why-redis",children:"Why Redis?"}),"\n",(0,s.jsx)(n.p,{children:"Redis gave us:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Low-latency"})," reads and writes"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Time-ordered data"})," using ZSETs (via score = timestamp)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Native TTL support"}),", if needed in later versions"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"In-memory performance"})," \u2014ideal for real-time CGs"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"storage-structure",children:"Storage Structure"}),"\n",(0,s.jsx)(n.p,{children:"Each user\u2019s interactions were stored using a composite key format, uniquely identifying the user and interaction type. This structure allowed efficient organization and quick retrieval of recent activity for recommendation generation:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"userId_eventType \u2192 ZSET[...(pid, ts)...]\n"})}),"\n",(0,s.jsx)(n.p,{children:"Within each ZSET:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"timestamp"})," served as the score, maintaining temporal order"]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"productId"})," (optionally with metadata) was the ",(0,s.jsx)(n.strong,{children:"value"})]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This allowed us to efficiently retrieve the interactions with HTTP-based API server with two query modes:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Fetch the ",(0,s.jsx)(n.strong,{children:"last k interactions"})," of a specific type for a given user with ",(0,s.jsx)(n.code,{children:"ZREVRANGE(userId_eventType, count)"})]}),"\n",(0,s.jsxs)(n.li,{children:["Retrieve ",(0,s.jsx)(n.strong,{children:"all interactions within a time range"})," (e.g., last 24 hours) with ",(0,s.jsx)(n.code,{children:"ZREVRANGEBYSCORE(userId_eventType, timeRange)"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"built-in-guardrails",children:"Built-in Guardrails"}),"\n",(0,s.jsx)(n.p,{children:"Since Redis was the sole store, we implemented High Availability (HA) to prevent data loss. To optimize memory usage, we also enforced size limits per event type\u2014only storing the last k interactions per user, with older entries getting truncated."}),"\n",(0,s.jsx)(n.h2,{id:"conclusion-laying-the-foundation-for-real-time-ml",children:"Conclusion: Laying the Foundation for Real-Time ML"}),"\n",(0,s.jsxs)(n.p,{children:["In this first phase, we tackled the ",(0,s.jsx)(n.strong,{children:"fundamentals"}),"\u2014shifting from batch-based recommendations to a ",(0,s.jsx)(n.strong,{children:"real-time Recommendation"})," using ML platform that could keep up with Meesho\u2019s growth."]}),"\n",(0,s.jsxs)(n.p,{children:["With the ",(0,s.jsx)(n.strong,{children:"IOP Framework"}),", ",(0,s.jsx)(n.strong,{children:"Online Feature Store"}),", and ",(0,s.jsx)(n.strong,{children:"Interaction Store"}),", we built the core infrastructure to support real-time personalization at scale. These wins have already unlocked:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"\u2705 Faster, more dynamic recommendations for millions of users."}),"\n",(0,s.jsx)(n.li,{children:"\u2705 Better infrastructure efficiency, reducing wasted compute power."}),"\n",(0,s.jsx)(n.li,{children:"\u2705 A flexible, modular system that allows for further experimentation."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["But this is just the beginning. While we've solved key challenges, ",(0,s.jsx)(n.strong,{children:"certain roadblocks remain"})," \u2014from optimizing ",(0,s.jsx)(n.strong,{children:"cost-performance trade-offs"})," to ",(0,s.jsx)(n.strong,{children:"seamlessly evolving schemas"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This foundational work laid the path for a reliable and scalable ",(0,s.jsx)(n.strong,{children:"real-time feature serving layer"}),"."]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},9930:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/bharatmlstack-72e1796337bfa224dee2a0f59ec4e2da.png"}}]); \ No newline at end of file diff --git a/docs/assets/js/09dd5be9.be7fd2aa.js b/docs/assets/js/09dd5be9.be7fd2aa.js new file mode 100644 index 00000000..c4d40aef --- /dev/null +++ b/docs/assets/js/09dd5be9.be7fd2aa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6273],{395:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/interaction-store-v0-68167b64c6e462ef2f177f0f86d55bda.png"},1164:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/bms-7399e8796d2cd24617c432518ce3f312.png"},1757:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/old-batch-arch-bc2cedbc1fed0fc6f08479ba8fe52996.png"},3983:e=>{e.exports=JSON.parse('{"permalink":"/BharatMLStack/blog/post-one","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-one/index.md","source":"@site/blog/bharatmlstack-history/post-one/index.md","title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","description":"BharatMLStack","date":"2022-11-15T00:00:00.000Z","tags":[{"inline":true,"label":"online-feature-store","permalink":"/BharatMLStack/blog/tags/online-feature-store"},{"inline":true,"label":"interaction-store","permalink":"/BharatMLStack/blog/tags/interaction-store"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"}],"readingTime":10.25,"hasTruncateMarker":false,"authors":[{"name":"Adarsha Das","title":"Senior Architect @ Meesho","url":"https://github.com/a0d00kc","imageURL":"https://github.com/a0d00kc.png","key":"adarsha","page":null},{"name":"Aditya Kumar","title":"Lead Software Engineer @ Meesho","url":"https://github.com/Adit2607","imageURL":"https://github.com/Adit2607.png","key":"aditya","page":null},{"name":"Bhawani Singh","title":"Architect @ Meesho","url":"https://github.com/singh-bhawani","imageURL":"https://github.com/singh-bhawani.png","key":"bhawani","page":null},{"name":"Jigar Dave","title":"Lead Software Engineer @ Meesho","url":"https://github.com/jigarpatel26","imageURL":"https://github.com/jigarpatel26.png","key":"jigar","page":null}],"frontMatter":{"slug":"post-one","title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","authors":["adarsha","aditya","bhawani","jigar"],"date":"2022-11-15T00:00:00.000Z","tags":["online-feature-store","interaction-store","mlplatform","meesho"]},"unlisted":false,"prevItem":{"title":"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)","permalink":"/BharatMLStack/blog/post-two"}}')},5017:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/online-feature-store-v0-86ec0010947ae24621f39ebd0d1729ca.png"},7848:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/first-gen-arch-7c0b286810aecb7eff42b48f51caee1f.png"},8453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>o});var t=i(6540);const s={},r=t.createContext(s);function a(e){const n=t.useContext(r);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(r.Provider,{value:n},e.children)}},8733:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/schema-d699efc400ed0f83bba421c1f55ab211.png"},8831:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>c,frontMatter:()=>a,metadata:()=>t,toc:()=>d});var t=i(3983),s=i(4848),r=i(8453);const a={slug:"post-one",title:"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)",authors:["adarsha","aditya","bhawani","jigar"],date:new Date("2022-11-15T00:00:00.000Z"),tags:["online-feature-store","interaction-store","mlplatform","meesho"]},o=void 0,l={authorsImageUrls:[void 0,void 0,void 0,void 0]},d=[{value:"The Genesis: How a Friday Night Roast Sparked Meesho\u2019s ML Platform",id:"the-genesis-how-a-friday-night-roast-sparked-meeshos-ml-platform",level:2},{value:"The Turning Point: From Batch to Real-Time",id:"the-turning-point-from-batch-to-real-time",level:2},{value:"First Generation Design",id:"first-generation-design",level:2},{value:"1. IOP Framework: A Real-Time DAG Executor",id:"1-iop-framework-a-real-time-dag-executor",level:3},{value:"2. Online Feature Store - 0th Version",id:"2-online-feature-store---0th-version",level:3},{value:"3. Interaction Store - 0th Version",id:"3-interaction-store---0th-version",level:3},{value:"Building the Online Feature Store - 0th Version",id:"building-the-online-feature-store---0th-version",level:2},{value:"Choosing the Right Tech Stack",id:"choosing-the-right-tech-stack",level:3},{value:"Streamlining the Data Flow",id:"streamlining-the-data-flow",level:3},{value:"The Challenges: Data Format and Storage",id:"the-challenges-data-format-and-storage",level:2},{value:"Feature Consistency",id:"feature-consistency",level:3},{value:"TTL Granularity",id:"ttl-granularity",level:3},{value:"Extensibility Across Databases",id:"extensibility-across-databases",level:3},{value:"Overcoming Technical Constraints",id:"overcoming-technical-constraints",level:2},{value:"The Solution: Schema Separation",id:"the-solution-schema-separation",level:2},{value:"Tracking Changes in Feature Groups",id:"tracking-changes-in-feature-groups",level:2},{value:"Common Real-World Scenarios:",id:"common-real-world-scenarios",level:3},{value:"The Solution: Schema Versioning",id:"the-solution-schema-versioning",level:2},{value:"Backward Compatibility",id:"backward-compatibility",level:3},{value:"Partial Availability Handling",id:"partial-availability-handling",level:3},{value:"Safe Writes Without Pipeline Pauses",id:"safe-writes-without-pipeline-pauses",level:3},{value:"Interaction Store - 0th Version",id:"interaction-store---0th-version",level:2},{value:"Event Ingestion",id:"event-ingestion",level:2},{value:"Storage Design",id:"storage-design",level:2},{value:"Why Redis?",id:"why-redis",level:3},{value:"Storage Structure",id:"storage-structure",level:3},{value:"Built-in Guardrails",id:"built-in-guardrails",level:3},{value:"Conclusion: Laying the Foundation for Real-Time ML",id:"conclusion-laying-the-foundation-for-real-time-ml",level:2}];function h(e){const n={a:"a",br:"br",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"BharatMLStack",src:i(1164).A+"",width:"1396",height:"460"})}),"\n",(0,s.jsx)(n.h2,{id:"the-genesis-how-a-friday-night-roast-sparked-meeshos-ml-platform",children:"The Genesis: How a Friday Night Roast Sparked Meesho\u2019s ML Platform"}),"\n",(0,s.jsx)(n.p,{children:"It all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting\u2014until one remark hit a little too close to home:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.em,{children:'"Why are we still crunching data for Monthly Active Users (MAU) when the next day it\u2019s all about Daily Active Users (DAU)?"'})}),"\n",(0,s.jsx)(n.p,{children:"The laughter died down, and the question lingered. When we regrouped on Monday\u2014clear-headed and slightly reflective\u2014we decided to dig into the numbers. What they discovered was quite revealing: a large portion of compute resources wasn\u2019t being put to good use.\nMuch of the system\u2019s effort was spent supporting users who weren\u2019t actively engaging, and even for new users, the experience wasn\u2019t optimized to make a meaningful impact."}),"\n",(0,s.jsxs)(n.p,{children:["At the same time, Meesho had just launched a company-wide initiative to reduce costs\u2014and every team had to contribute. This realization sparked the journey that would eventually lead to the ",(0,s.jsx)(n.strong,{children:"Meesho ML Platform"}),", known today as ",(0,s.jsx)(n.strong,{children:"BharatMLStack"}),"."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(1757).A+"",width:"1600",height:"1078"})}),"\n",(0,s.jsx)(n.p,{children:"Before the ML Platform, our recommendation and ranking pipelines followed a batch processing approach:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Data Ingestion"}),": The Data Platform team executed ETL jobs to ingest raw user data\u2014including user profiles, interaction logs, and product impressions\u2014into designated S3 buckets."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Layer 1"}),": Embedding Generation: On the Data Science side, Spark jobs pulled data from multiple S3 sources, cleaned and preprocessed it, and applied matrix factorization to generate user and item embeddings. The processed data and embeddings were then stored back in S3 in a structured format."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Layer 2"}),": Candidate Generation (CG): In this stage, Spark jobs leveraged embeddings and historical interaction data to generate candidate recommendations for users. These candidate lists were subsequently written to S3."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Layer 3"}),": Ranking and Merging \u2013 A final round of processing ranked the generated candidates using ML models, combined different candidate lists, and stored the final ranked recommendations in a caching system."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Serving"}),': A microservice retrieved ranked recommendations from an in-memory data store via exposed APIs, delivering personalized listings across key surfaces such as "For You" and Category Landing Pages (CLP).']}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This approach held up well\u2014until Meesho started seeing a significant surge in traffic."}),"\n",(0,s.jsx)(n.h2,{id:"the-turning-point-from-batch-to-real-time",children:"The Turning Point: From Batch to Real-Time"}),"\n",(0,s.jsxs)(n.p,{children:["At this time, the team was iterating on new ",(0,s.jsx)(n.strong,{children:"Ranker models"}),", and real-time inference seemed like the next logical step. But Rankers needed ",(0,s.jsx)(n.strong,{children:"real-time feature retrieval"}),", which meant an ",(0,s.jsx)(n.strong,{children:"online feature store"})," had to be built first."]}),"\n",(0,s.jsxs)(n.p,{children:["Exploring open-source options led to ",(0,s.jsx)(n.strong,{children:"cost vs. performance trade-offs"}),", but Meesho\u2019s surging traffic meant that ",(0,s.jsx)(n.strong,{children:"latency and stability were non-negotiable"}),". After multiple debates and stakeholder discussions, a bold decision was made:"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.em,{children:"We would build our own feature store."})}),"\n",(0,s.jsxs)(n.p,{children:["Meanwhile, efforts began to bring ",(0,s.jsx)(n.strong,{children:"Candidate Generators (CGs)"})," to real-time. The challenge? ",(0,s.jsx)(n.strong,{children:"Storing and retrieving user interactions quickly enough"})," to power real-time recommendations."]}),"\n",(0,s.jsxs)(n.p,{children:["As the team dove deeper, a new roadblock emerged:",(0,s.jsx)(n.br,{}),"\n","Our ML jobs were orchestrated using ",(0,s.jsx)(n.strong,{children:"Airflow DAGs"}),", giving data scientists flexibility in experimentation. But transitioning to real-time execution threatened this agility. Every change would now require backend engineering support, ",(0,s.jsx)(n.strong,{children:"slowing down iteration cycles"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["That\u2019s when the idea struck:",(0,s.jsx)(n.br,{}),"\n","We needed a ",(0,s.jsx)(n.strong,{children:"framework for real-time DAG execution"}),"\u2014one that preserved the same flexibility as Airflow but worked for ",(0,s.jsx)(n.strong,{children:"streaming data"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This moment shaped the ",(0,s.jsx)(n.strong,{children:"next phase of our journey"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"first-generation-design",children:"First Generation Design"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(7848).A+"",width:"1600",height:"1006"})}),"\n",(0,s.jsx)(n.h1,{id:"laying-the-groundwork-the-first-gen-ml-platform",children:"Laying the Groundwork: The First-Gen ML Platform"}),"\n",(0,s.jsx)(n.p,{children:"To solve these challenges, the team built three foundational components:"}),"\n",(0,s.jsx)(n.h3,{id:"1-iop-framework-a-real-time-dag-executor",children:"1. IOP Framework: A Real-Time DAG Executor"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Reusable Nodes"}),": Each DAG node (e.g., an invocation to a CG service, a ranker, or a filter) had to be implemented only once. After that, it could be reused across any workflow by referencing it in config."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Config-driven Dynamic Graphs"}),": Execution graphs were defined as adjacency lists stored in ",(0,s.jsx)(n.strong,{children:"ZooKeeper"}),", allowing teams to modify the sequence or structure of operations without touching application code."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Plug-and-play CGs"}),": The Candidate Generator interface was preserved, so a single CG node could call any CG service by passing ",(0,s.jsx)(n.code,{children:"cg_name"})," in the request. This drastically reduced the code surface area and improved maintainability."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Production-Grade DAGs"}),": DAGs were designed to execute in ",(0,s.jsx)(n.strong,{children:"low-latency real-time environments"}),", with support for ",(0,s.jsx)(n.strong,{children:"parallel execution, retries, and branching"}),"."]}),"\n"]}),"\n",(0,s.jsx)("u",{children:(0,s.jsx)(n.a,{href:"https://www.meesho.io/blog/rebuilding-meeshos-ranking-platform",children:"More about IOP DAG"})}),"\n",(0,s.jsx)(n.h3,{id:"2-online-feature-store---0th-version",children:"2. Online Feature Store - 0th Version"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Used ",(0,s.jsx)(n.strong,{children:"Cassandra"})," and ",(0,s.jsx)(n.strong,{children:"Redis"})," for low-latency feature serving."]}),"\n",(0,s.jsxs)(n.li,{children:["Maintained feature consistency using ",(0,s.jsx)(n.strong,{children:"Feature Groups"})," with TTL-based expiry."]}),"\n",(0,s.jsxs)(n.li,{children:["A hybrid schema was used: feature keys stored in ",(0,s.jsx)(n.strong,{children:"ZooKeeper"}),", data stored in ",(0,s.jsx)(n.strong,{children:"compact arrays"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"3-interaction-store---0th-version",children:"3. Interaction Store - 0th Version"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Captured real-time user interactions like clicks, orders, and add-to-cart events."}),"\n",(0,s.jsxs)(n.li,{children:["Stored event data in ",(0,s.jsx)(n.strong,{children:"Redis ZSETs (sorted sets)"})," to enable fast lookups for recommendation engines."]}),"\n",(0,s.jsxs)(n.li,{children:["Provided an API to fetch a user's ",(0,s.jsxs)(n.strong,{children:["last ",(0,s.jsx)(n.em,{children:"k"})," interactions"]})," or ",(0,s.jsx)(n.strong,{children:"interactions within a time window"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["With these components in place, ",(0,s.jsx)(n.strong,{children:"real-time ML at Meesho became a reality"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"This was just the beginning."}),"\n",(0,s.jsx)(n.h2,{id:"building-the-online-feature-store---0th-version",children:"Building the Online Feature Store - 0th Version"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt text",src:i(5017).A+"",width:"1574",height:"562"})}),"\n",(0,s.jsx)(n.h3,{id:"choosing-the-right-tech-stack",children:"Choosing the Right Tech Stack"}),"\n",(0,s.jsxs)(n.p,{children:["We spent considerable time evaluating various databases, caches, and communication protocols for our ",(0,s.jsx)(n.strong,{children:"online feature store"}),". After carefully weighing ",(0,s.jsx)(n.strong,{children:"cost, latency, throughput"}),", and ",(0,s.jsx)(n.strong,{children:"operational stability"}),", we settled on a combination of:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Cassandra"})," and ",(0,s.jsx)(n.strong,{children:"Redis"})," for storage"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"gRPC + Proto3"})," as our communication layer"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"streamlining-the-data-flow",children:"Streamlining the Data Flow"}),"\n",(0,s.jsx)(n.p,{children:"To keep things simple in the initial version:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature engineering jobs"})," wrote raw outputs to an ",(0,s.jsx)(n.strong,{children:"S3 bucket"})]}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.strong,{children:"daily feature push job"}),":","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Read from S3"}),"\n",(0,s.jsxs)(n.li,{children:["Grouped related features into ",(0,s.jsx)(n.strong,{children:"Feature Groups"})," (ensuring consistency)"]}),"\n",(0,s.jsxs)(n.li,{children:["Pushed them to ",(0,s.jsx)(n.strong,{children:"Kafka"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"For features requiring frequent updates:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Ad-hoc jobs"})," computed features in higher frequency"]}),"\n",(0,s.jsxs)(n.li,{children:["These jobs pushed to both ",(0,s.jsx)(n.strong,{children:"Kafka"})," and ",(0,s.jsx)(n.strong,{children:"S3"})," (S3 preserved historical data for future model training)"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"the-challenges-data-format-and-storage",children:"The Challenges: Data Format and Storage"}),"\n",(0,s.jsxs)(n.p,{children:["One of the most critical design challenges was how to store feature data ",(0,s.jsx)(n.strong,{children:"efficiently and consistently"}),", especially in databases like ",(0,s.jsx)(n.strong,{children:"Cassandra"})," and ",(0,s.jsx)(n.strong,{children:"Redis"}),", which come with unique storage constraints."]}),"\n",(0,s.jsx)(n.p,{children:"We had to solve for three key requirements:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"feature-consistency",children:"Feature Consistency"}),"\n",(0,s.jsxs)(n.p,{children:["When a feature group contains features like ",(0,s.jsx)(n.code,{children:"order_count_1h"})," and ",(0,s.jsx)(n.code,{children:"click_count_1h"}),", both must reflect the ",(0,s.jsx)(n.strong,{children:"same time window"}),". Inconsistent updates would lead to ",(0,s.jsx)(n.strong,{children:"unreliable model predictions"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"ttl-granularity",children:"TTL Granularity"}),"\n",(0,s.jsxs)(n.p,{children:["Each feature group required an ",(0,s.jsx)(n.strong,{children:"expiry timestamp"}),", so that ",(0,s.jsx)(n.strong,{children:"all features within it expired together"}),"\u2014preserving consistency during reads."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"extensibility-across-databases",children:"Extensibility Across Databases"}),"\n",(0,s.jsxs)(n.p,{children:["We anticipated that infra needs would evolve. To future-proof our system, the data format was designed to be ",(0,s.jsx)(n.strong,{children:"decoupled from DB-specific layouts"}),", enabling portability to systems like ",(0,s.jsx)(n.strong,{children:"ScyllaDB"}),", ",(0,s.jsx)(n.strong,{children:"DynamoDB"}),", ",(0,s.jsx)(n.strong,{children:"HBase"}),", or ",(0,s.jsx)(n.strong,{children:"BigTable"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"overcoming-technical-constraints",children:"Overcoming Technical Constraints"}),"\n",(0,s.jsx)(n.p,{children:'At the time, we were using Cassandra, which not only imposed a soft limit of 75 columns per row, but also exhibited significant performance degradation as the number of columns increased further, particularly in memory constrained machines. Wide rows caused high memory usage during reads, unpredictable latencies due to heavy deserialization overhead, and inefficiencies during compactions and repairs. This ruled out the naive "one column per feature" approach. We needed a format that was compact, minimized the number of columns, and remained efficient and portable across different storage systems.'}),"\n",(0,s.jsx)(n.h2,{id:"the-solution-schema-separation",children:"The Solution: Schema Separation"}),"\n",(0,s.jsx)(n.p,{children:"We introduced the concept of Feature Groups\u2014logical groupings of features that must remain consistent with one another.\nTo represent these groups efficiently, we adopted a layered storage approach:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature Labels (Keys)"})," were stored in ZooKeeper, serving as the schema."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature Values"})," were stored as a comma-separated string array in Cassandra or Redis."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Expiry Timestamp and Schema Version"})," were appended using a semi-colon delimiter at the end of the string."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"feature_1_value,feature_2_value,feature_3_value;expiry_ts\n"})}),"\n",(0,s.jsx)(n.p,{children:"This format allowed:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Consistent writes and reads at the group level"}),"\n",(0,s.jsx)(n.li,{children:"Easy parsing of feature values using the schema lookup from ZooKeeper"}),"\n",(0,s.jsx)(n.li,{children:"Efficient storage with minimal DB column usage"}),"\n",(0,s.jsx)(n.li,{children:"Support for per-group TTLs and schema evolution"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"tracking-changes-in-feature-groups",children:"Tracking Changes in Feature Groups"}),"\n",(0,s.jsx)(n.p,{children:"Feature groups don\u2019t stay static. As models evolve, features get added, renamed, or removed. But schema changes often go live before the data is ready\u2014and stopping ingestion just to wait for everything to align isn't feasible."}),"\n",(0,s.jsx)(n.h3,{id:"common-real-world-scenarios",children:"Common Real-World Scenarios:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"A new feature is added to the schema, but ingestion jobs still use the older schema version."}),"\n",(0,s.jsx)(n.li,{children:"Ongoing writes don\u2019t include the newly added feature, and stopping ingestion would break freshness for existing features."}),"\n",(0,s.jsx)(n.li,{children:"During serving, models request a mix of old and new features, depending on rollout stages."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"the-solution-schema-versioning",children:"The Solution: Schema Versioning"}),"\n",(0,s.jsx)(n.p,{children:"We solved this with versioned feature group schemas, which unlocked several capabilities:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"backward-compatibility",children:"Backward Compatibility"}),"\n","Older ingestion jobs can continue writing using older schema versions. During reads, the system uses the schema version embedded in the value to interpret the data correctly."]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"partial-availability-handling",children:"Partial Availability Handling"}),"\n","During inference, if some features in the request aren\u2019t available (due to rollout delays or missing data), the system serves default values, ensuring the inference call doesn\u2019t fail."]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"safe-writes-without-pipeline-pauses",children:"Safe Writes Without Pipeline Pauses"}),"\n","With schema versioning, we no longer had to stop ingestion pipelines for schema updates. Writes using previous versions can continue safely, and downstream consumers evolve independently.\nThis design gave us the flexibility to move fast without breaking things\u2014preserving data quality, enabling experimentation, and ensuring reliability at scale."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(8733).A+"",width:"1600",height:"599"})}),"\n",(0,s.jsx)(n.h2,{id:"interaction-store---0th-version",children:"Interaction Store - 0th Version"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(395).A+"",width:"1600",height:"518"})}),"\n",(0,s.jsxs)(n.p,{children:["To power real-time Candidate Generators (CGs), we needed fast access to user behavior signals\u2014like what a user recently clicked, ordered, or added to their cart. These interactions form the basis for many real-time recommendations, such as ",(0,s.jsx)(n.strong,{children:"Similar Products"}),", ",(0,s.jsx)(n.strong,{children:"People Also Viewed"}),", or ",(0,s.jsx)(n.strong,{children:"Recently Ordered Again"}),".\nFor the ",(0,s.jsx)(n.strong,{children:"0th version"})," of the Interaction Store, we focused on a design that was ",(0,s.jsx)(n.strong,{children:"simple, fast, and reliable"})," \u2014 optimized for high-throughput ingestion and low-latency lookups."]}),"\n",(0,s.jsx)(n.h2,{id:"event-ingestion",children:"Event Ingestion"}),"\n",(0,s.jsx)(n.p,{children:"We instrumented our backend services to emit key user interaction events to Kafka in real time. These included:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Click"}),"\n",(0,s.jsx)(n.li,{children:"Order"}),"\n",(0,s.jsx)(n.li,{children:"Add to Cart"}),"\n",(0,s.jsx)(n.li,{children:"Wishlist"}),"\n",(0,s.jsx)(n.li,{children:"Share"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Each event carried essential metadata:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"userId \u2014 uniquely identifies the user"}),"\n",(0,s.jsx)(n.li,{children:"productId \u2014 the item being interacted with"}),"\n",(0,s.jsx)(n.li,{children:"timestamp \u2014 the moment the interaction occurred"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This decoupled the interaction logging from storage, allowing ingestion and consumption to scale independently."}),"\n",(0,s.jsx)(n.h2,{id:"storage-design",children:"Storage Design"}),"\n",(0,s.jsx)(n.p,{children:"To store these events, we built Kafka consumers that processed the incoming streams and wrote the data into Redis, using sorted sets (ZSETs) as the primary data structure."}),"\n",(0,s.jsx)(n.h3,{id:"why-redis",children:"Why Redis?"}),"\n",(0,s.jsx)(n.p,{children:"Redis gave us:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Low-latency"})," reads and writes"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Time-ordered data"})," using ZSETs (via score = timestamp)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Native TTL support"}),", if needed in later versions"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"In-memory performance"})," \u2014ideal for real-time CGs"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"storage-structure",children:"Storage Structure"}),"\n",(0,s.jsx)(n.p,{children:"Each user\u2019s interactions were stored using a composite key format, uniquely identifying the user and interaction type. This structure allowed efficient organization and quick retrieval of recent activity for recommendation generation:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"userId_eventType \u2192 ZSET[...(pid, ts)...]\n"})}),"\n",(0,s.jsx)(n.p,{children:"Within each ZSET:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"timestamp"})," served as the score, maintaining temporal order"]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"productId"})," (optionally with metadata) was the ",(0,s.jsx)(n.strong,{children:"value"})]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This allowed us to efficiently retrieve the interactions with HTTP-based API server with two query modes:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Fetch the ",(0,s.jsx)(n.strong,{children:"last k interactions"})," of a specific type for a given user with ",(0,s.jsx)(n.code,{children:"ZREVRANGE(userId_eventType, count)"})]}),"\n",(0,s.jsxs)(n.li,{children:["Retrieve ",(0,s.jsx)(n.strong,{children:"all interactions within a time range"})," (e.g., last 24 hours) with ",(0,s.jsx)(n.code,{children:"ZREVRANGEBYSCORE(userId_eventType, timeRange)"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"built-in-guardrails",children:"Built-in Guardrails"}),"\n",(0,s.jsx)(n.p,{children:"Since Redis was the sole store, we implemented High Availability (HA) to prevent data loss. To optimize memory usage, we also enforced size limits per event type\u2014only storing the last k interactions per user, with older entries getting truncated."}),"\n",(0,s.jsx)(n.h2,{id:"conclusion-laying-the-foundation-for-real-time-ml",children:"Conclusion: Laying the Foundation for Real-Time ML"}),"\n",(0,s.jsxs)(n.p,{children:["In this first phase, we tackled the ",(0,s.jsx)(n.strong,{children:"fundamentals"}),"\u2014shifting from batch-based recommendations to a ",(0,s.jsx)(n.strong,{children:"real-time Recommendation"})," using ML platform that could keep up with Meesho\u2019s growth."]}),"\n",(0,s.jsxs)(n.p,{children:["With the ",(0,s.jsx)(n.strong,{children:"IOP Framework"}),", ",(0,s.jsx)(n.strong,{children:"Online Feature Store"}),", and ",(0,s.jsx)(n.strong,{children:"Interaction Store"}),", we built the core infrastructure to support real-time personalization at scale. These wins have already unlocked:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"\u2705 Faster, more dynamic recommendations for millions of users."}),"\n",(0,s.jsx)(n.li,{children:"\u2705 Better infrastructure efficiency, reducing wasted compute power."}),"\n",(0,s.jsx)(n.li,{children:"\u2705 A flexible, modular system that allows for further experimentation."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["But this is just the beginning. While we've solved key challenges, ",(0,s.jsx)(n.strong,{children:"certain roadblocks remain"})," \u2014from optimizing ",(0,s.jsx)(n.strong,{children:"cost-performance trade-offs"})," to ",(0,s.jsx)(n.strong,{children:"seamlessly evolving schemas"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This foundational work laid the path for a reliable and scalable ",(0,s.jsx)(n.strong,{children:"real-time feature serving layer"}),"."]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}}}]); \ No newline at end of file diff --git a/docs/assets/js/0a89f5c9.190be82b.js b/docs/assets/js/0a89f5c9.190be82b.js new file mode 100644 index 00000000..cf662ca4 --- /dev/null +++ b/docs/assets/js/0a89f5c9.190be82b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7508],{5641:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"inferflow/v1.0.0/functionalities","title":"Key Functionalities","description":"Overview","source":"@site/docs/inferflow/v1.0.0/functionalities.md","sourceDirName":"inferflow/v1.0.0","slug":"/inferflow/v1.0.0/functionalities","permalink":"/BharatMLStack/inferflow/v1.0.0/functionalities","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/inferflow/v1.0.0/functionalities.md","tags":[],"version":"current","sidebarPosition":2,"frontMatter":{"title":"Key Functionalities","sidebar_position":2},"sidebar":"tutorialSidebar","previous":{"title":"Architecture","permalink":"/BharatMLStack/inferflow/v1.0.0/architecture"},"next":{"title":"Configuration Guide","permalink":"/BharatMLStack/inferflow/v1.0.0/configuration"}}');var s=i(4848),t=i(8453);const l={title:"Key Functionalities",sidebar_position:2},o="Inferflow - Key Functionalities",c={},d=[{value:"Overview",id:"overview",level:2},{value:"Core Capabilities",id:"core-capabilities",level:2},{value:"Graph-Driven Feature Retrieval",id:"graph-driven-feature-retrieval",level:3},{value:"DAG Topology Executor",id:"dag-topology-executor",level:3},{value:"Multi-Pattern Inference APIs",id:"multi-pattern-inference-apis",level:2},{value:"PointWise Inference",id:"pointwise-inference",level:3},{value:"PairWise Inference",id:"pairwise-inference",level:3},{value:"SlateWise Inference",id:"slatewise-inference",level:3},{value:"Entity & Legacy API",id:"entity--legacy-api",level:2},{value:"RetrieveModelScore",id:"retrievemodelscore",level:3},{value:"Component Types",id:"component-types",level:2},{value:"FeatureInitComponent",id:"featureinitcomponent",level:3},{value:"FeatureComponent",id:"featurecomponent",level:3},{value:"PredatorComponent",id:"predatorcomponent",level:3},{value:"NumerixComponent",id:"numerixcomponent",level:3},{value:"Feature Retrieval Pipeline",id:"feature-retrieval-pipeline",level:2},{value:"Key Resolution",id:"key-resolution",level:3},{value:"Batched Retrieval",id:"batched-retrieval",level:3},{value:"In-Memory Caching",id:"in-memory-caching",level:3},{value:"Data Types",id:"data-types",level:2},{value:"Inference Logging",id:"inference-logging",level:2},{value:"Serialization Formats",id:"serialization-formats",level:3},{value:"Sampling Controls",id:"sampling-controls",level:3},{value:"Log Content",id:"log-content",level:3},{value:"Configuration Hot-Reload",id:"configuration-hot-reload",level:2},{value:"Performance Characteristics",id:"performance-characteristics",level:2},{value:"Concurrency Model",id:"concurrency-model",level:3},{value:"Memory Efficiency",id:"memory-efficiency",level:3},{value:"Serialization",id:"serialization",level:3},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"inferflow---key-functionalities",children:"Inferflow - Key Functionalities"})}),"\n",(0,s.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,s.jsxs)(n.p,{children:["Inferflow is a high-performance, config-driven ML inference orchestration engine built in ",(0,s.jsx)(n.strong,{children:"Go"}),". It provides ",(0,s.jsx)(n.strong,{children:"no-code feature retrieval"}),", ",(0,s.jsx)(n.strong,{children:"DAG-based execution"}),", and ",(0,s.jsx)(n.strong,{children:"multi-pattern model inference"})," \u2014 enabling ML teams to onboard new models through configuration changes alone."]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"core-capabilities",children:"Core Capabilities"}),"\n",(0,s.jsx)(n.h3,{id:"graph-driven-feature-retrieval",children:"Graph-Driven Feature Retrieval"}),"\n",(0,s.jsx)(n.p,{children:"Inferflow's defining feature is its ability to resolve entity relationships and retrieve features through configurable DAG topologies \u2014 no custom code required."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"How it works:"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.code,{children:"model_config_id"})," maps to a pre-defined DAG of components"]}),"\n",(0,s.jsxs)(n.li,{children:["Context entity IDs (e.g., ",(0,s.jsx)(n.code,{children:"userId"}),", ",(0,s.jsx)(n.code,{children:"productIds"}),") are provided at request time"]}),"\n",(0,s.jsxs)(n.li,{children:["The DAG resolves intermediate entity relationships (e.g., extracting ",(0,s.jsx)(n.code,{children:"category"})," from ",(0,s.jsx)(n.code,{children:"product"})," to fetch ",(0,s.jsx)(n.code,{children:"user x category"})," features)"]}),"\n",(0,s.jsx)(n.li,{children:"Features are fetched in parallel from the Online Feature Store"}),"\n",(0,s.jsx)(n.li,{children:"A 2D feature matrix is assembled and passed to model scoring"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Impact:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"New models require only a config update \u2014 no code changes"}),"\n",(0,s.jsx)(n.li,{children:"Feature consistency is guaranteed across experiments"}),"\n",(0,s.jsx)(n.li,{children:"Iteration cycles drop from days to minutes"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"dag-topology-executor",children:"DAG Topology Executor"}),"\n",(0,s.jsxs)(n.p,{children:["The execution engine uses ",(0,s.jsx)(n.strong,{children:"Kahn's algorithm"})," for topological ordering with ",(0,s.jsx)(n.strong,{children:"concurrent goroutine execution"})," at each level:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'component_dependency: {\n "feature_initializer": ["fs_user", "fs_product"],\n "fs_user": ["ranker"],\n "fs_product": ["ranker"],\n "ranker": ["reranker"],\n "reranker": []\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"This config defines:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"feature_initializer"})," runs first (zero in-degree)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"fs_user"})," and ",(0,s.jsx)(n.code,{children:"fs_product"})," run ",(0,s.jsx)(n.strong,{children:"in parallel"})," after init"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"ranker"})," runs after both feature components complete"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"reranker"})," runs after the ranker"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Key properties:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Cycle detection via in-degree analysis"}),"\n",(0,s.jsx)(n.li,{children:"DAG topologies cached using Murmur3 hashing (Ristretto cache)"}),"\n",(0,s.jsxs)(n.li,{children:["Components are registered and resolved via a ",(0,s.jsx)(n.code,{children:"ComponentProvider"})]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"multi-pattern-inference-apis",children:"Multi-Pattern Inference APIs"}),"\n",(0,s.jsxs)(n.p,{children:["Inferflow supports three inference patterns via the ",(0,s.jsx)(n.strong,{children:"Predict API"}),", each designed for different ML use cases:"]}),"\n",(0,s.jsx)(n.h3,{id:"pointwise-inference",children:"PointWise Inference"}),"\n",(0,s.jsx)(n.p,{children:"Score each target independently against context features."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-protobuf",children:"rpc InferPointWise(PredictRequest) returns (PredictResponse);\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Use cases:"})," Click-through rate prediction, fraud scoring, relevance ranking"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Input:"})," Context features + list of targets (e.g., products)\n",(0,s.jsx)(n.strong,{children:"Output:"})," Per-target scores"]}),"\n",(0,s.jsx)(n.h3,{id:"pairwise-inference",children:"PairWise Inference"}),"\n",(0,s.jsx)(n.p,{children:"Score pairs of targets relative to each other."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-protobuf",children:"rpc InferPairWise(PredictRequest) returns (PredictResponse);\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Use cases:"})," Preference learning, comparison-based ranking"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Input:"})," Context features + targets + pair indices (first/second)\n",(0,s.jsx)(n.strong,{children:"Output:"})," Per-pair scores + optional per-target scores"]}),"\n",(0,s.jsx)(n.h3,{id:"slatewise-inference",children:"SlateWise Inference"}),"\n",(0,s.jsx)(n.p,{children:"Score groups (slates) of targets together, capturing inter-item effects."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-protobuf",children:"rpc InferSlateWise(PredictRequest) returns (PredictResponse);\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Use cases:"})," Whole-page optimization, slate-level reranking, diversity-aware scoring"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Input:"})," Context features + targets + slate definitions (target indices per slate)\n",(0,s.jsx)(n.strong,{children:"Output:"})," Per-slate scores + optional per-target scores"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"entity--legacy-api",children:"Entity & Legacy API"}),"\n",(0,s.jsx)(n.h3,{id:"retrievemodelscore",children:"RetrieveModelScore"}),"\n",(0,s.jsx)(n.p,{children:"The original Inferflow API for entity-based feature retrieval and scoring:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-protobuf",children:"service Inferflow {\n rpc RetrieveModelScore(InferflowRequestProto) returns (InferflowResponseProto);\n}\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Request structure:"})}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Field"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"entities"})}),(0,s.jsx)(n.td,{children:"List of entity types with their IDs and optional inline features"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"model_config_id"})}),(0,s.jsx)(n.td,{children:"Identifies the model configuration (DAG, components, response format)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"tracking_id"})}),(0,s.jsx)(n.td,{children:"Request-level tracing identifier"})]})]})]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Entity structure:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"entity"}),": Entity type label (e.g., ",(0,s.jsx)(n.code,{children:'"user"'}),", ",(0,s.jsx)(n.code,{children:'"product"'}),")"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"ids"}),": List of entity IDs"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"features"}),": Optional inline features (name + per-ID values)"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"component-types",children:"Component Types"}),"\n",(0,s.jsx)(n.h3,{id:"featureinitcomponent",children:"FeatureInitComponent"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Role:"})," Root DAG node \u2014 initializes the shared ",(0,s.jsx)(n.code,{children:"ComponentMatrix"}),"."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Sets up rows from entity IDs"}),"\n",(0,s.jsx)(n.li,{children:"Populates schema columns (string + byte) for all downstream components"}),"\n",(0,s.jsxs)(n.li,{children:["For slate APIs: initializes ",(0,s.jsx)(n.code,{children:"SlateData"})," with ",(0,s.jsx)(n.code,{children:"slate_target_indices"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"featurecomponent",children:"FeatureComponent"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Role:"})," Fetches features from the Online Feature Store (OnFS) for a specific entity type."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Reads ",(0,s.jsx)(n.code,{children:"FSKeys"})," from config to extract lookup keys from the matrix"]}),"\n",(0,s.jsx)(n.li,{children:"Batches unique entities and calls OnFS via gRPC"}),"\n",(0,s.jsxs)(n.li,{children:["Optional ",(0,s.jsx)(n.strong,{children:"in-memory caching"})," keyed by ",(0,s.jsx)(n.code,{children:"model_id:version:component:entity"})]}),"\n",(0,s.jsx)(n.li,{children:"Writes binary feature values into matrix byte columns"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Column naming convention:"})," ",(0,s.jsx)(n.code,{children:"entity_label:feature_group:feature_name"})]}),"\n",(0,s.jsx)(n.h3,{id:"predatorcomponent",children:"PredatorComponent"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Role:"})," Calls model serving endpoints for inference."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Builds feature payloads from matrix columns with type conversion"}),"\n",(0,s.jsxs)(n.li,{children:["Supports ",(0,s.jsx)(n.strong,{children:"percentage-based traffic routing"})," across multiple model endpoints"]}),"\n",(0,s.jsxs)(n.li,{children:["Handles ",(0,s.jsx)(n.strong,{children:"slate-level inference"}),": per-slate matrix \u2192 separate inference \u2192 scores to ",(0,s.jsx)(n.code,{children:"SlateData"})]}),"\n",(0,s.jsxs)(n.li,{children:["Configurable ",(0,s.jsx)(n.strong,{children:"calibration"})," and ",(0,s.jsx)(n.strong,{children:"batch sizing"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"numerixcomponent",children:"NumerixComponent"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Role:"})," Calls the Numerix compute engine for operations like reranking."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Uses ",(0,s.jsx)(n.code,{children:"ScoreMapping"})," config to map matrix columns to compute inputs"]}),"\n",(0,s.jsx)(n.li,{children:"Writes a single score column back to the matrix"}),"\n",(0,s.jsx)(n.li,{children:"Supports slate mode for per-slate compute operations"}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"feature-retrieval-pipeline",children:"Feature Retrieval Pipeline"}),"\n",(0,s.jsx)(n.h3,{id:"key-resolution",children:"Key Resolution"}),"\n",(0,s.jsxs)(n.p,{children:["Feature components use ",(0,s.jsx)(n.code,{children:"FSKeys"})," configuration to dynamically resolve entity keys:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "FSKeys": {\n "schema": ["user_id"],\n "col": "user:profile:user_id"\n }\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The component reads key values from the existing matrix columns, enabling ",(0,s.jsx)(n.strong,{children:"chained entity resolution"})," \u2014 e.g., fetch product entity first, extract category, then fetch user x category features."]}),"\n",(0,s.jsx)(n.h3,{id:"batched-retrieval",children:"Batched Retrieval"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Features are fetched via ",(0,s.jsx)(n.code,{children:"FeatureService.RetrieveFeatures"})," gRPC call"]}),"\n",(0,s.jsx)(n.li,{children:"Requests are batched by unique entity keys"}),"\n",(0,s.jsx)(n.li,{children:"Configurable batch size and deadline per component"}),"\n",(0,s.jsxs)(n.li,{children:["Auth via ",(0,s.jsx)(n.code,{children:"CALLER_ID"})," and ",(0,s.jsx)(n.code,{children:"CALLER_TOKEN"})," metadata"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"in-memory-caching",children:"In-Memory Caching"}),"\n",(0,s.jsx)(n.p,{children:"Optional per-component caching reduces OnFS load:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Cache key: ",(0,s.jsx)(n.code,{children:"model_id:cache_version:component_name:entity_key"})]}),"\n",(0,s.jsx)(n.li,{children:"Configurable TTL per component"}),"\n",(0,s.jsx)(n.li,{children:"Zero-GC-overhead cache implementation available"}),"\n",(0,s.jsx)(n.li,{children:"Cache hit/miss metrics tracked via StatsD"}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"data-types",children:"Data Types"}),"\n",(0,s.jsx)(n.p,{children:"Inferflow supports comprehensive ML data types for feature encoding and model input/output:"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Data Type"}),(0,s.jsx)(n.th,{children:"Variants"}),(0,s.jsx)(n.th,{children:"Usage"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Integers"})}),(0,s.jsx)(n.td,{children:"int8, int16, int32, int64"}),(0,s.jsx)(n.td,{children:"Categorical encodings, counts, IDs"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Floats"})}),(0,s.jsx)(n.td,{children:"float8 (e4m3, e5m2), float16, float32, float64"}),(0,s.jsx)(n.td,{children:"Continuous features, embeddings, scores"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Strings"})}),(0,s.jsx)(n.td,{children:"Variable length"}),(0,s.jsx)(n.td,{children:"Categories, metadata"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Booleans"})}),(0,s.jsx)(n.td,{children:"Bit-packed"}),(0,s.jsx)(n.td,{children:"Binary indicators"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Vectors"})}),(0,s.jsx)(n.td,{children:"All scalar types"}),(0,s.jsx)(n.td,{children:"Embeddings, feature arrays"})]})]})]}),"\n",(0,s.jsxs)(n.p,{children:["Type conversion is handled by the ",(0,s.jsx)(n.code,{children:"datatypeconverter"})," package with optimized float8 implementations."]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"inference-logging",children:"Inference Logging"}),"\n",(0,s.jsx)(n.p,{children:"Inferflow supports async inference logging to Kafka for model monitoring and debugging:"}),"\n",(0,s.jsx)(n.h3,{id:"serialization-formats",children:"Serialization Formats"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Format"}),(0,s.jsx)(n.th,{children:"Use Case"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Proto"})}),(0,s.jsx)(n.td,{children:"Default, compact"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Arrow"})}),(0,s.jsx)(n.td,{children:"Columnar analytics"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Parquet"})}),(0,s.jsx)(n.td,{children:"Long-term storage, query-friendly"})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"sampling-controls",children:"Sampling Controls"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Config"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"LoggingPerc"})}),(0,s.jsx)(n.td,{children:"Percentage of requests to log (0-100)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"LogBatchSize"})}),(0,s.jsx)(n.td,{children:"Batch size for log message grouping"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"LogFeatures"})}),(0,s.jsx)(n.td,{children:"Specific features to include in logs"})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"log-content",children:"Log Content"}),"\n",(0,s.jsxs)(n.p,{children:["Each ",(0,s.jsx)(n.code,{children:"InferflowLog"})," message includes:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"user_id"}),", ",(0,s.jsx)(n.code,{children:"tracking_id"}),", ",(0,s.jsx)(n.code,{children:"model_config_id"})]}),"\n",(0,s.jsx)(n.li,{children:"Entity IDs and feature values"}),"\n",(0,s.jsx)(n.li,{children:"Model scores and metadata"}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"configuration-hot-reload",children:"Configuration Hot-Reload"}),"\n",(0,s.jsxs)(n.p,{children:["Model configurations are stored in ",(0,s.jsx)(n.strong,{children:"etcd"})," and support ",(0,s.jsx)(n.strong,{children:"live updates without redeployment"}),":"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Inferflow registers watchers on etcd config paths"}),"\n",(0,s.jsxs)(n.li,{children:["On config change, watchers trigger ",(0,s.jsx)(n.code,{children:"ReloadModelConfigMapAndRegisterComponents"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"ConfigMap"})," is updated in memory"]}),"\n",(0,s.jsx)(n.li,{children:"Feature schemas are re-initialized"}),"\n",(0,s.jsx)(n.li,{children:"DAG components are re-registered"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This enables:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Adding new models in production without restarts"}),"\n",(0,s.jsx)(n.li,{children:"A/B testing with different model configurations"}),"\n",(0,s.jsx)(n.li,{children:"Instant rollback by reverting etcd config"}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"performance-characteristics",children:"Performance Characteristics"}),"\n",(0,s.jsx)(n.h3,{id:"concurrency-model",children:"Concurrency Model"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"DAG components at the same level execute concurrently in goroutines"}),"\n",(0,s.jsx)(n.li,{children:"Feature retrieval is parallelized across entity types"}),"\n",(0,s.jsx)(n.li,{children:"External gRPC calls use connection pooling"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"memory-efficiency",children:"Memory Efficiency"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Built in Go \u2014 significantly lower memory footprint than Java equivalents (~80% reduction)"}),"\n",(0,s.jsxs)(n.li,{children:["Object pooling for ",(0,s.jsx)(n.code,{children:"ComponentMatrix"})," and serialization buffers"]}),"\n",(0,s.jsx)(n.li,{children:"In-memory cache with zero-GC-overhead option (freecache)"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"serialization",children:"Serialization"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"gRPC with Proto3 for all external communication"}),"\n",(0,s.jsxs)(n.li,{children:["Binary feature encoding in the ",(0,s.jsx)(n.code,{children:"ComponentMatrix"})," for minimal overhead"]}),"\n",(0,s.jsx)(n.li,{children:"Configurable compression for Kafka logging"}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,s.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,s.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,s.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,s.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,s.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)("div",{align:"center",children:(0,s.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,s.jsx)("div",{align:"center",children:(0,s.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>l,x:()=>o});var r=i(6540);const s={},t=r.createContext(s);function l(e){const n=r.useContext(t);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/0fff8dc8.7a470540.js b/docs/assets/js/0fff8dc8.fcba975a.js similarity index 98% rename from docs/assets/js/0fff8dc8.7a470540.js rename to docs/assets/js/0fff8dc8.fcba975a.js index 87386b52..2fb035eb 100644 --- a/docs/assets/js/0fff8dc8.7a470540.js +++ b/docs/assets/js/0fff8dc8.fcba975a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9596],{5958:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>t,metadata:()=>r,toc:()=>o});const r=JSON.parse('{"id":"quick-start/v1.0.0/quick-start","title":"Quick Start","description":"Discord","source":"@site/docs/quick-start/v1.0.0/quick-start.md","sourceDirName":"quick-start/v1.0.0","slug":"/quick-start/v1.0.0/quick-start","permalink":"/BharatMLStack/quick-start/v1.0.0/quick-start","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/quick-start/v1.0.0/quick-start.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"Quick Start","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"Quick Start","permalink":"/BharatMLStack/category/quick-start"},"next":{"title":"Trufflebox UI","permalink":"/BharatMLStack/category/trufflebox-ui"}}');var i=s(4848),l=s(8453);const t={title:"Quick Start",sidebar_position:1},c="BharatML Stack Quick Start Guide",a={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"System Components",id:"system-components",level:2},{value:"Quick Start",id:"quick-start",level:2},{value:"Starting the System",id:"starting-the-system",level:3},{value:"Testing Different Versions",id:"testing-different-versions",level:3},{value:"Stopping the System",id:"stopping-the-system",level:3},{value:"Accessing Services",id:"accessing-services",level:2},{value:"Frontend UI",id:"frontend-ui",level:3},{value:"API Endpoints",id:"api-endpoints",level:3},{value:"Database Access",id:"database-access",level:3},{value:"Feature Store API Examples",id:"feature-store-api-examples",level:2},{value:"gRPC API Commands",id:"grpc-api-commands",level:3},{value:"Sample Request Bodies",id:"sample-request-bodies",level:3},{value:"Key Points",id:"key-points",level:3},{value:"Response Format Differences",id:"response-format-differences",level:3},{value:"Managing Services",id:"managing-services",level:2},{value:"Viewing Logs",id:"viewing-logs",level:3},{value:"Service Management",id:"service-management",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Common Issues",id:"common-issues",level:3},{value:"Service Dependencies",id:"service-dependencies",level:3},{value:"Development",id:"development",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,l.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"bharatml-stack-quick-start-guide",children:"BharatML Stack Quick Start Guide"})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:(0,i.jsx)(n.img,{src:"https://img.shields.io/badge/Discord-Join%20Chat-7289da?style=flat&logo=discord&logoColor=white",alt:"Discord"})})}),"\n",(0,i.jsx)(n.p,{children:"A quick way to get the BharatML Stack Online Feature Store platform up and running locally for development and testing."}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Docker and Docker Compose"}),"\n",(0,i.jsx)(n.li,{children:"Go 1.22 or later"}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"nc"})," (netcat) command for connectivity checks"]}),"\n",(0,i.jsx)(n.li,{children:"Bash shell"}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"grpcurl"})," for testing gRPC API endpoints (install from ",(0,i.jsx)(n.a,{href:"https://github.com/fullstorydev/grpcurl",children:"https://github.com/fullstorydev/grpcurl"}),")"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"system-components",children:"System Components"}),"\n",(0,i.jsx)(n.p,{children:"BharatMLStack's Online Feature Store consists of several interconnected services:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Infrastructure Services:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"ScyllaDB"}),": NoSQL database for high-performance feature storage"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"MySQL"}),": Relational database for metadata and configuration"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Redis"}),": In-memory data store for caching"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"etcd"}),": Distributed key-value store for service coordination"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Application Services:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Horizon"}),": Backend API service (runs on port 8082)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Trufflebox UI"}),": Frontend web interface (runs on port 3000)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Online Feature Store gRPC API Server"}),": High-performance gRPC interface (runs on port 8089)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"etcd Workbench"}),": etcd management interface (runs on port 8081)"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"All services are orchestrated using Docker Compose with pre-built images from GitHub Container Registry (GHCR)."}),"\n",(0,i.jsx)(n.h2,{id:"quick-start",children:"Quick Start"}),"\n",(0,i.jsx)(n.h3,{id:"starting-the-system",children:"Starting the System"}),"\n",(0,i.jsx)(n.p,{children:"Run the start script to set up your workspace and launch all services:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"./start.sh\n"})}),"\n",(0,i.jsx)(n.h3,{id:"testing-different-versions",children:"Testing Different Versions"}),"\n",(0,i.jsx)(n.p,{children:"You can easily test different versions of the application services by setting environment variables:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Test specific versions [Replace with actual versions]\nONFS_VERSION=v1.2.3 HORIZON_VERSION=v2.1.0 TRUFFLEBOX_VERSION=v1.0.5 ./start.sh\n\n# Or set them in your workspace and run docker-compose directly\ncd workspace\nONFS_VERSION=main docker-compose up -d onfs-api-server\n"})}),"\n",(0,i.jsx)(n.p,{children:"Available version formats:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"latest"})," (default) - Latest stable release"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"main"})," - Latest development build"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"v1.2.3"})," - Specific version tag"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sha-abcd1234"})," - Specific commit SHA"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"This will:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Check for Go installation (1.22+ required)"}),"\n",(0,i.jsx)(n.li,{children:"Create a workspace directory with configuration files"}),"\n",(0,i.jsxs)(n.li,{children:["Pull and start all services using ",(0,i.jsx)(n.code,{children:"docker-compose up -d"})]}),"\n",(0,i.jsx)(n.li,{children:"Wait for services to become healthy"}),"\n",(0,i.jsx)(n.li,{children:"Initialize databases with required schemas"}),"\n",(0,i.jsx)(n.li,{children:"Display access information and helpful commands"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Once complete, you can access:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Trufflebox UI"}),": ",(0,i.jsx)(n.a,{href:"http://localhost:3000",children:"http://localhost:3000"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Horizon API"}),": ",(0,i.jsx)(n.a,{href:"http://localhost:8082",children:"http://localhost:8082"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Online Feature Store gRPC API"}),": ",(0,i.jsx)(n.a,{href:"http://localhost:8089",children:"http://localhost:8089"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"etcd Workbench"}),": ",(0,i.jsx)(n.a,{href:"http://localhost:8081",children:"http://localhost:8081"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"stopping-the-system",children:"Stopping the System"}),"\n",(0,i.jsx)(n.p,{children:"To stop all services:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"./stop.sh\n"})}),"\n",(0,i.jsx)(n.p,{children:"To stop and completely purge all containers, volumes, and workspace:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"./stop.sh --purge\n"})}),"\n",(0,i.jsx)(n.h2,{id:"accessing-services",children:"Accessing Services"}),"\n",(0,i.jsx)(n.h3,{id:"frontend-ui",children:"Frontend UI"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"URL"}),": ",(0,i.jsx)(n.a,{href:"http://localhost:3000",children:"http://localhost:3000"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Default admin credentials"}),":","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Email: ",(0,i.jsx)(n.code,{children:"admin@admin.com"})]}),"\n",(0,i.jsxs)(n.li,{children:["Password: ",(0,i.jsx)(n.code,{children:"admin"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"api-endpoints",children:"API Endpoints"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Horizon API"}),": ",(0,i.jsx)(n.a,{href:"http://localhost:8082",children:"http://localhost:8082"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Health check: ",(0,i.jsx)(n.a,{href:"http://localhost:8082/health",children:"http://localhost:8082/health"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"ONFS gRPC API"}),": ",(0,i.jsx)(n.a,{href:"http://localhost:8089",children:"http://localhost:8089"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Health check: ",(0,i.jsx)(n.a,{href:"http://localhost:8089/health/self",children:"http://localhost:8089/health/self"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"database-access",children:"Database Access"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"MySQL"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Host: localhost"}),"\n",(0,i.jsx)(n.li,{children:"Port: 3306"}),"\n",(0,i.jsx)(n.li,{children:"Username: root"}),"\n",(0,i.jsx)(n.li,{children:"Password: root"}),"\n",(0,i.jsx)(n.li,{children:"Database: testdb"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"ScyllaDB"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Host: localhost"}),"\n",(0,i.jsx)(n.li,{children:"Port: 9042"}),"\n",(0,i.jsx)(n.li,{children:"Keyspace: onfs"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Redis"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Host: localhost"}),"\n",(0,i.jsx)(n.li,{children:"Port: 6379"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"etcd"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Endpoint: ",(0,i.jsx)(n.a,{href:"http://localhost:2379",children:"http://localhost:2379"})]}),"\n",(0,i.jsxs)(n.li,{children:["Workbench: ",(0,i.jsx)(n.a,{href:"http://localhost:8081",children:"http://localhost:8081"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"feature-store-api-examples",children:"Feature Store API Examples"}),"\n",(0,i.jsx)(n.h3,{id:"grpc-api-commands",children:"gRPC API Commands"}),"\n",(0,i.jsxs)(n.p,{children:["Use the following ",(0,i.jsx)(n.code,{children:"grpcurl"})," commands to interact with the Online Feature Store gRPC API:"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Persist Features:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'grpcurl -plaintext -H "online-feature-store-caller-id: " -H "online-feature-store-auth-token: " -d \'\' localhost:8089 persist.FeatureService/PersistFeatures\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Retrieve Features (Decoded):"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'grpcurl -plaintext -H "online-feature-store-caller-id: " -H "online-feature-store-auth-token: " -d \'\' localhost:8089 retrieve.FeatureService/RetrieveDecodedResult\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Retrieve Features (Binary):"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'grpcurl -plaintext -H "online-feature-store-caller-id: " -H "online-feature-store-auth-token: " -d \'\' localhost:8089 retrieve.FeatureService/RetrieveFeatures\n'})}),"\n",(0,i.jsx)(n.h3,{id:"sample-request-bodies",children:"Sample Request Bodies"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Single Feature Group Persist:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "data": [{\n "key_values": ["10"],\n "feature_values": [{\n "values": {"fp32_values": [123.45]}\n }]\n }],\n "entity_label": "catalog",\n "feature_group_schema": [{\n "label": "int_fg",\n "feature_labels": ["id"]\n }],\n "keys_schema": ["catalog_id"]\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Single Feature Group Retrieve:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "entity_label": "catalog",\n "feature_groups": [{\n "label": "int_fg",\n "feature_labels": ["id"]\n }],\n "keys_schema": ["catalog_id"],\n "keys": [{"cols": ["10"]}]\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Multiple Feature Groups Persist:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "data": [\n {\n "key_values": ["1"],\n "feature_values": [\n {"values": {"fp32_values": [28.5]}},\n {"values": {"string_values": ["Bharat"]}}\n ]\n },\n {\n "key_values": ["2"],\n "feature_values": [\n {"values": {"fp32_values": [32.0]}},\n {"values": {"string_values": ["India"]}}\n ]\n }\n ],\n "entity_label": "catalog",\n "feature_group_schema": [\n {"label": "int_fg", "feature_labels": ["id"]},\n {"label": "string_fg", "feature_labels": ["name"]}\n ],\n "keys_schema": ["catalog_id"]\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Multiple Feature Groups Retrieve:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "entity_label": "catalog",\n "feature_groups": [\n {"label": "int_fg", "feature_labels": ["id"]},\n {"label": "string_fg", "feature_labels": ["name"]}\n ],\n "keys_schema": ["catalog_id"],\n "keys": [\n {"cols": ["1"]},\n {"cols": ["2"]}\n ]\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Vector Feature Group Persist:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "data": [{\n "key_values": ["123"],\n "feature_values": [{\n "values": {\n "vector": [{\n "values": {"fp32_values": [1.0, 2.0, 3.0, 4.0]}\n }]\n }\n }]\n }],\n "entity_label": "catalog",\n "feature_group_schema": [{\n "label": "vector_fg",\n "feature_labels": ["embedding"]\n }],\n "keys_schema": ["catalog_id"]\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Vector Feature Group Retrieve:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "entity_label": "catalog",\n "feature_groups": [{\n "label": "vector_fg",\n "feature_labels": ["embedding"]\n }],\n "keys_schema": ["catalog_id"],\n "keys": [{"cols": ["123"]}]\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"key-points",children:"Key Points"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Only one type per feature value block:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"feature_values"})," is a list, and each item in the list has only one value type populated"]}),"\n",(0,i.jsxs)(n.li,{children:["For example: one item has only ",(0,i.jsx)(n.code,{children:"fp32_values"}),", another has only ",(0,i.jsx)(n.code,{children:"int64_values"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Field Types:"}),"\nThe following value types are supported:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"fp32_values"}),": ",(0,i.jsx)(n.code,{children:"float32[]"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"fp64_values"}),": ",(0,i.jsx)(n.code,{children:"float64[]"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"int32_values"}),": ",(0,i.jsx)(n.code,{children:"int32[]"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"int64_values"}),": ",(0,i.jsx)(n.code,{children:"string[]"})," (because JSON doesn't support 64-bit ints directly)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"uint32_values"}),": ",(0,i.jsx)(n.code,{children:"uint32[]"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"uint64_values"}),": ",(0,i.jsx)(n.code,{children:"string[]"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"string_values"}),": ",(0,i.jsx)(n.code,{children:"string[]"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"bool_values"}),": ",(0,i.jsx)(n.code,{children:"bool[]"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"vector"}),": list of objects with nested values (used for embedded features)"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"response-format-differences",children:"Response Format Differences"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Retrieve Features (Binary)"}),": Returns data in binary format for optimal performance and reduced network overhead"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Retrieve Features (Decoded)"}),": Returns data in human-readable string format for easier debugging and development purposes"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"managing-services",children:"Managing Services"}),"\n",(0,i.jsx)(n.h3,{id:"viewing-logs",children:"Viewing Logs"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# View logs for all services\ncd workspace && docker-compose logs -f\n\n# View logs for specific services\ncd workspace && docker-compose logs -f horizon\ncd workspace && docker-compose logs -f trufflebox-ui\ncd workspace && docker-compose logs -f onfs-api-server\n"})}),"\n",(0,i.jsx)(n.h3,{id:"service-management",children:"Service Management"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Restart a specific service\ncd workspace && docker-compose restart horizon\n\n# Stop all services\ncd workspace && docker-compose down\n\n# Start services again\ncd workspace && docker-compose up -d\n\n# Check service status\ncd workspace && docker-compose ps\n"})}),"\n",(0,i.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,i.jsx)(n.h3,{id:"common-issues",children:"Common Issues"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Port conflicts"}),": Ensure ports 3000, 8081, 8082, 8089, 9042, 3306, 6379, and 2379 are not in use by other applications."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Docker network issues"}),": If containers can't communicate, try recreating:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker network rm onfs-network\ndocker network create onfs-network\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Service health checks failing"}),": Check if all infrastructure services (databases) are running:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd workspace && docker-compose ps\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Image pull issues"}),": Ensure you have access to GitHub Container Registry:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker login ghcr.io\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://github.com/tzfun/etcd-workbench/blob/master/README.md",children:"How to use Etcd Workbench ?"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"service-dependencies",children:"Service Dependencies"}),"\n",(0,i.jsx)(n.p,{children:"Services start in the following order:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Infrastructure services (ScyllaDB, MySQL, Redis, etcd)"}),"\n",(0,i.jsx)(n.li,{children:"Online Feature Store gRPC API Server"}),"\n",(0,i.jsx)(n.li,{children:"Horizon (depends on databases + ONFS API)"}),"\n",(0,i.jsx)(n.li,{children:"Trufflebox UI (depends on Horizon)"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"If a service fails to start, check its dependencies are healthy first."}),"\n",(0,i.jsx)(n.h2,{id:"development",children:"Development"}),"\n",(0,i.jsx)(n.p,{children:"The workspace directory contains all runtime configuration:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"workspace/docker-compose.yml"})," - Complete service orchestration"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"workspace/check_db_and_init.sh"})," - Database initialization script"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"You can modify environment variables in the docker-compose.yml file and restart services."}),"\n",(0,i.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,i.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,i.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\ud83d\udcac ",(0,i.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,i.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,i.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,i.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,i.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>c});var r=s(6540);const i={},l=r.createContext(i);function t(e){const n=r.useContext(l);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9596],{5958:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>t,metadata:()=>r,toc:()=>o});const r=JSON.parse('{"id":"quick-start/v1.0.0/quick-start","title":"Quick Start","description":"Discord","source":"@site/docs/quick-start/v1.0.0/quick-start.md","sourceDirName":"quick-start/v1.0.0","slug":"/quick-start/v1.0.0/quick-start","permalink":"/BharatMLStack/quick-start/v1.0.0/quick-start","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/quick-start/v1.0.0/quick-start.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"Quick Start","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"Quick Start","permalink":"/BharatMLStack/category/quick-start"},"next":{"title":"Trufflebox UI","permalink":"/BharatMLStack/category/trufflebox-ui"}}');var i=s(4848),l=s(8453);const t={title:"Quick Start",sidebar_position:1},c="BharatML Stack Quick Start Guide",a={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"System Components",id:"system-components",level:2},{value:"Quick Start",id:"quick-start",level:2},{value:"Starting the System",id:"starting-the-system",level:3},{value:"Testing Different Versions",id:"testing-different-versions",level:3},{value:"Stopping the System",id:"stopping-the-system",level:3},{value:"Accessing Services",id:"accessing-services",level:2},{value:"Frontend UI",id:"frontend-ui",level:3},{value:"API Endpoints",id:"api-endpoints",level:3},{value:"Database Access",id:"database-access",level:3},{value:"Feature Store API Examples",id:"feature-store-api-examples",level:2},{value:"gRPC API Commands",id:"grpc-api-commands",level:3},{value:"Sample Request Bodies",id:"sample-request-bodies",level:3},{value:"Key Points",id:"key-points",level:3},{value:"Response Format Differences",id:"response-format-differences",level:3},{value:"Managing Services",id:"managing-services",level:2},{value:"Viewing Logs",id:"viewing-logs",level:3},{value:"Service Management",id:"service-management",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Common Issues",id:"common-issues",level:3},{value:"Service Dependencies",id:"service-dependencies",level:3},{value:"Development",id:"development",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,l.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"bharatml-stack-quick-start-guide",children:"BharatML Stack Quick Start Guide"})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:(0,i.jsx)(n.img,{src:"https://img.shields.io/badge/Discord-Join%20Chat-7289da?style=flat&logo=discord&logoColor=white",alt:"Discord"})})}),"\n",(0,i.jsx)(n.p,{children:"A quick way to get the BharatML Stack Online Feature Store platform up and running locally for development and testing."}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Docker and Docker Compose"}),"\n",(0,i.jsx)(n.li,{children:"Go 1.22 or later"}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"nc"})," (netcat) command for connectivity checks"]}),"\n",(0,i.jsx)(n.li,{children:"Bash shell"}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"grpcurl"})," for testing gRPC API endpoints (install from ",(0,i.jsx)(n.a,{href:"https://github.com/fullstorydev/grpcurl",children:"https://github.com/fullstorydev/grpcurl"}),")"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"system-components",children:"System Components"}),"\n",(0,i.jsx)(n.p,{children:"BharatMLStack's Online Feature Store consists of several interconnected services:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Infrastructure Services:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"ScyllaDB"}),": NoSQL database for high-performance feature storage"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"MySQL"}),": Relational database for metadata and configuration"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Redis"}),": In-memory data store for caching"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"etcd"}),": Distributed key-value store for service coordination"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Application Services:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Horizon"}),": Backend API service (runs on port 8082)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Trufflebox UI"}),": Frontend web interface (runs on port 3000)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Online Feature Store gRPC API Server"}),": High-performance gRPC interface (runs on port 8089)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"etcd Workbench"}),": etcd management interface (runs on port 8081)"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"All services are orchestrated using Docker Compose with pre-built images from GitHub Container Registry (GHCR)."}),"\n",(0,i.jsx)(n.h2,{id:"quick-start",children:"Quick Start"}),"\n",(0,i.jsx)(n.h3,{id:"starting-the-system",children:"Starting the System"}),"\n",(0,i.jsx)(n.p,{children:"Run the start script to set up your workspace and launch all services:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"./start.sh\n"})}),"\n",(0,i.jsx)(n.h3,{id:"testing-different-versions",children:"Testing Different Versions"}),"\n",(0,i.jsx)(n.p,{children:"You can easily test different versions of the application services by setting environment variables:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Test specific versions [Replace with actual versions]\nONFS_VERSION=v1.2.3 HORIZON_VERSION=v2.1.0 TRUFFLEBOX_VERSION=v1.0.5 ./start.sh\n\n# Or set them in your workspace and run docker-compose directly\ncd workspace\nONFS_VERSION=main docker-compose up -d onfs-api-server\n"})}),"\n",(0,i.jsx)(n.p,{children:"Available version formats:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"latest"})," (default) - Latest stable release"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"main"})," - Latest development build"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"v1.2.3"})," - Specific version tag"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sha-abcd1234"})," - Specific commit SHA"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"This will:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Check for Go installation (1.22+ required)"}),"\n",(0,i.jsx)(n.li,{children:"Create a workspace directory with configuration files"}),"\n",(0,i.jsxs)(n.li,{children:["Pull and start all services using ",(0,i.jsx)(n.code,{children:"docker-compose up -d"})]}),"\n",(0,i.jsx)(n.li,{children:"Wait for services to become healthy"}),"\n",(0,i.jsx)(n.li,{children:"Initialize databases with required schemas"}),"\n",(0,i.jsx)(n.li,{children:"Display access information and helpful commands"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Once complete, you can access:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Trufflebox UI"}),": ",(0,i.jsx)(n.a,{href:"http://localhost:3000",children:"http://localhost:3000"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Horizon API"}),": ",(0,i.jsx)(n.a,{href:"http://localhost:8082",children:"http://localhost:8082"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Online Feature Store gRPC API"}),": ",(0,i.jsx)(n.a,{href:"http://localhost:8089",children:"http://localhost:8089"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"etcd Workbench"}),": ",(0,i.jsx)(n.a,{href:"http://localhost:8081",children:"http://localhost:8081"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"stopping-the-system",children:"Stopping the System"}),"\n",(0,i.jsx)(n.p,{children:"To stop all services:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"./stop.sh\n"})}),"\n",(0,i.jsx)(n.p,{children:"To stop and completely purge all containers, volumes, and workspace:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"./stop.sh --purge\n"})}),"\n",(0,i.jsx)(n.h2,{id:"accessing-services",children:"Accessing Services"}),"\n",(0,i.jsx)(n.h3,{id:"frontend-ui",children:"Frontend UI"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"URL"}),": ",(0,i.jsx)(n.a,{href:"http://localhost:3000",children:"http://localhost:3000"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Default admin credentials"}),":","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Email: ",(0,i.jsx)(n.code,{children:"admin@admin.com"})]}),"\n",(0,i.jsxs)(n.li,{children:["Password: ",(0,i.jsx)(n.code,{children:"admin"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"api-endpoints",children:"API Endpoints"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Horizon API"}),": ",(0,i.jsx)(n.a,{href:"http://localhost:8082",children:"http://localhost:8082"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Health check: ",(0,i.jsx)(n.a,{href:"http://localhost:8082/health",children:"http://localhost:8082/health"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"ONFS gRPC API"}),": ",(0,i.jsx)(n.a,{href:"http://localhost:8089",children:"http://localhost:8089"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Health check: ",(0,i.jsx)(n.a,{href:"http://localhost:8089/health/self",children:"http://localhost:8089/health/self"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"database-access",children:"Database Access"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"MySQL"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Host: localhost"}),"\n",(0,i.jsx)(n.li,{children:"Port: 3306"}),"\n",(0,i.jsx)(n.li,{children:"Username: root"}),"\n",(0,i.jsx)(n.li,{children:"Password: root"}),"\n",(0,i.jsx)(n.li,{children:"Database: testdb"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"ScyllaDB"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Host: localhost"}),"\n",(0,i.jsx)(n.li,{children:"Port: 9042"}),"\n",(0,i.jsx)(n.li,{children:"Keyspace: onfs"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Redis"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Host: localhost"}),"\n",(0,i.jsx)(n.li,{children:"Port: 6379"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"etcd"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Endpoint: ",(0,i.jsx)(n.a,{href:"http://localhost:2379",children:"http://localhost:2379"})]}),"\n",(0,i.jsxs)(n.li,{children:["Workbench: ",(0,i.jsx)(n.a,{href:"http://localhost:8081",children:"http://localhost:8081"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"feature-store-api-examples",children:"Feature Store API Examples"}),"\n",(0,i.jsx)(n.h3,{id:"grpc-api-commands",children:"gRPC API Commands"}),"\n",(0,i.jsxs)(n.p,{children:["Use the following ",(0,i.jsx)(n.code,{children:"grpcurl"})," commands to interact with the Online Feature Store gRPC API:"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Persist Features:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'grpcurl -plaintext -H "online-feature-store-caller-id: " -H "online-feature-store-auth-token: " -d \'\' localhost:8089 persist.FeatureService/PersistFeatures\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Retrieve Features (Decoded):"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'grpcurl -plaintext -H "online-feature-store-caller-id: " -H "online-feature-store-auth-token: " -d \'\' localhost:8089 retrieve.FeatureService/RetrieveDecodedResult\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Retrieve Features (Binary):"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'grpcurl -plaintext -H "online-feature-store-caller-id: " -H "online-feature-store-auth-token: " -d \'\' localhost:8089 retrieve.FeatureService/RetrieveFeatures\n'})}),"\n",(0,i.jsx)(n.h3,{id:"sample-request-bodies",children:"Sample Request Bodies"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Single Feature Group Persist:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "data": [{\n "key_values": ["10"],\n "feature_values": [{\n "values": {"fp32_values": [123.45]}\n }]\n }],\n "entity_label": "catalog",\n "feature_group_schema": [{\n "label": "int_fg",\n "feature_labels": ["id"]\n }],\n "keys_schema": ["catalog_id"]\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Single Feature Group Retrieve:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "entity_label": "catalog",\n "feature_groups": [{\n "label": "int_fg",\n "feature_labels": ["id"]\n }],\n "keys_schema": ["catalog_id"],\n "keys": [{"cols": ["10"]}]\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Multiple Feature Groups Persist:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "data": [\n {\n "key_values": ["1"],\n "feature_values": [\n {"values": {"fp32_values": [28.5]}},\n {"values": {"string_values": ["Bharat"]}}\n ]\n },\n {\n "key_values": ["2"],\n "feature_values": [\n {"values": {"fp32_values": [32.0]}},\n {"values": {"string_values": ["India"]}}\n ]\n }\n ],\n "entity_label": "catalog",\n "feature_group_schema": [\n {"label": "int_fg", "feature_labels": ["id"]},\n {"label": "string_fg", "feature_labels": ["name"]}\n ],\n "keys_schema": ["catalog_id"]\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Multiple Feature Groups Retrieve:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "entity_label": "catalog",\n "feature_groups": [\n {"label": "int_fg", "feature_labels": ["id"]},\n {"label": "string_fg", "feature_labels": ["name"]}\n ],\n "keys_schema": ["catalog_id"],\n "keys": [\n {"cols": ["1"]},\n {"cols": ["2"]}\n ]\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Vector Feature Group Persist:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "data": [{\n "key_values": ["123"],\n "feature_values": [{\n "values": {\n "vector": [{\n "values": {"fp32_values": [1.0, 2.0, 3.0, 4.0]}\n }]\n }\n }]\n }],\n "entity_label": "catalog",\n "feature_group_schema": [{\n "label": "vector_fg",\n "feature_labels": ["embedding"]\n }],\n "keys_schema": ["catalog_id"]\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Vector Feature Group Retrieve:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "entity_label": "catalog",\n "feature_groups": [{\n "label": "vector_fg",\n "feature_labels": ["embedding"]\n }],\n "keys_schema": ["catalog_id"],\n "keys": [{"cols": ["123"]}]\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"key-points",children:"Key Points"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Only one type per feature value block:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"feature_values"})," is a list, and each item in the list has only one value type populated"]}),"\n",(0,i.jsxs)(n.li,{children:["For example: one item has only ",(0,i.jsx)(n.code,{children:"fp32_values"}),", another has only ",(0,i.jsx)(n.code,{children:"int64_values"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Field Types:"}),"\nThe following value types are supported:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"fp32_values"}),": ",(0,i.jsx)(n.code,{children:"float32[]"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"fp64_values"}),": ",(0,i.jsx)(n.code,{children:"float64[]"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"int32_values"}),": ",(0,i.jsx)(n.code,{children:"int32[]"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"int64_values"}),": ",(0,i.jsx)(n.code,{children:"string[]"})," (because JSON doesn't support 64-bit ints directly)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"uint32_values"}),": ",(0,i.jsx)(n.code,{children:"uint32[]"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"uint64_values"}),": ",(0,i.jsx)(n.code,{children:"string[]"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"string_values"}),": ",(0,i.jsx)(n.code,{children:"string[]"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"bool_values"}),": ",(0,i.jsx)(n.code,{children:"bool[]"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"vector"}),": list of objects with nested values (used for embedded features)"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"response-format-differences",children:"Response Format Differences"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Retrieve Features (Binary)"}),": Returns data in binary format for optimal performance and reduced network overhead"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Retrieve Features (Decoded)"}),": Returns data in human-readable string format for easier debugging and development purposes"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"managing-services",children:"Managing Services"}),"\n",(0,i.jsx)(n.h3,{id:"viewing-logs",children:"Viewing Logs"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# View logs for all services\ncd workspace && docker-compose logs -f\n\n# View logs for specific services\ncd workspace && docker-compose logs -f horizon\ncd workspace && docker-compose logs -f trufflebox-ui\ncd workspace && docker-compose logs -f onfs-api-server\n"})}),"\n",(0,i.jsx)(n.h3,{id:"service-management",children:"Service Management"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Restart a specific service\ncd workspace && docker-compose restart horizon\n\n# Stop all services\ncd workspace && docker-compose down\n\n# Start services again\ncd workspace && docker-compose up -d\n\n# Check service status\ncd workspace && docker-compose ps\n"})}),"\n",(0,i.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,i.jsx)(n.h3,{id:"common-issues",children:"Common Issues"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Port conflicts"}),": Ensure ports 3000, 8081, 8082, 8089, 9042, 3306, 6379, and 2379 are not in use by other applications."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Docker network issues"}),": If containers can't communicate, try recreating:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker network rm onfs-network\ndocker network create onfs-network\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Service health checks failing"}),": Check if all infrastructure services (databases) are running:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd workspace && docker-compose ps\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Image pull issues"}),": Ensure you have access to GitHub Container Registry:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker login ghcr.io\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://github.com/tzfun/etcd-workbench/blob/master/README.md",children:"How to use Etcd Workbench ?"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"service-dependencies",children:"Service Dependencies"}),"\n",(0,i.jsx)(n.p,{children:"Services start in the following order:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Infrastructure services (ScyllaDB, MySQL, Redis, etcd)"}),"\n",(0,i.jsx)(n.li,{children:"Online Feature Store gRPC API Server"}),"\n",(0,i.jsx)(n.li,{children:"Horizon (depends on databases + ONFS API)"}),"\n",(0,i.jsx)(n.li,{children:"Trufflebox UI (depends on Horizon)"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"If a service fails to start, check its dependencies are healthy first."}),"\n",(0,i.jsx)(n.h2,{id:"development",children:"Development"}),"\n",(0,i.jsx)(n.p,{children:"The workspace directory contains all runtime configuration:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"workspace/docker-compose.yml"})," - Complete service orchestration"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"workspace/check_db_and_init.sh"})," - Database initialization script"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"You can modify environment variables in the docker-compose.yml file and restart services."}),"\n",(0,i.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,i.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,i.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\ud83d\udcac ",(0,i.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,i.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,i.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,i.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,i.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>c});var r=s(6540);const i={},l=r.createContext(i);function t(e){const n=r.useContext(l);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/14064408.be0f96be.js b/docs/assets/js/14064408.74c23df4.js similarity index 75% rename from docs/assets/js/14064408.be0f96be.js rename to docs/assets/js/14064408.74c23df4.js index 1b02768a..d9f055a3 100644 --- a/docs/assets/js/14064408.be0f96be.js +++ b/docs/assets/js/14064408.74c23df4.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4582],{9416:t=>{t.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Quick Start","description":"Quick Start guide for BharatML Stack. Get up and running quickly with step-by-step instructions, sample data, and Docker Compose setup for local development and testing.","slug":"/category/quick-start","permalink":"/BharatMLStack/category/quick-start","sidebar":"tutorialSidebar","navigation":{"previous":{"title":"Release Notes","permalink":"/BharatMLStack/online-feature-store/v1.0.0/release-notes"},"next":{"title":"Quick Start","permalink":"/BharatMLStack/quick-start/v1.0.0/quick-start"}}}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4582],{9416:t=>{t.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Quick Start","description":"Quick Start guide for BharatML Stack. Get up and running quickly with step-by-step instructions, sample data, and Docker Compose setup for local development and testing.","slug":"/category/quick-start","permalink":"/BharatMLStack/category/quick-start","sidebar":"tutorialSidebar","navigation":{"previous":{"title":"Release Notes","permalink":"/BharatMLStack/inferflow/v1.0.0/release-notes"},"next":{"title":"Quick Start","permalink":"/BharatMLStack/quick-start/v1.0.0/quick-start"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/14eb3368.398ac934.js b/docs/assets/js/14eb3368.398ac934.js new file mode 100644 index 00000000..786e75d7 --- /dev/null +++ b/docs/assets/js/14eb3368.398ac934.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6969],{477:(e,s,n)=>{n.r(s),n.d(s,{default:()=>w});n(6540);var t=n(5500),r=n(6972),a=n(6025),i=n(4164),c=n(8774),l=n(5846),o=n(6654),d=n(1312),u=n(1107);const m={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var h=n(4848);function b({className:e,href:s,children:n}){return(0,h.jsx)(c.A,{href:s,className:(0,i.A)("card padding--lg",m.cardContainer,e),children:n})}function x({className:e,href:s,icon:n,title:t,description:r}){return(0,h.jsxs)(b,{href:s,className:e,children:[(0,h.jsxs)(u.A,{as:"h2",className:(0,i.A)("text--truncate",m.cardTitle),title:t,children:[n," ",t]}),r&&(0,h.jsx)("p",{className:(0,i.A)("text--truncate",m.cardDescription),title:r,children:r})]})}function p({item:e}){const s=(0,r.Nr)(e),n=function(){const{selectMessage:e}=(0,l.W)();return s=>e(s,(0,d.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:s}))}();return s?(0,h.jsx)(x,{className:e.className,href:s,icon:"\ud83d\uddc3\ufe0f",title:e.label,description:e.description??n(e.items.length)}):null}function v({item:e}){const s=(0,o.A)(e.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",n=(0,r.cC)(e.docId??void 0);return(0,h.jsx)(x,{className:e.className,href:e.href,icon:s,title:e.label,description:e.description??n?.description})}function g({item:e}){switch(e.type){case"link":return(0,h.jsx)(v,{item:e});case"category":return(0,h.jsx)(p,{item:e});default:throw new Error(`unknown item type ${JSON.stringify(e)}`)}}const f={docCardListItem:"docCardListItem_W1sv"};function j({className:e}){const s=(0,r.a4)();return(0,h.jsx)(N,{items:s,className:e})}function A({item:e}){return(0,h.jsx)("article",{className:(0,i.A)(f.docCardListItem,"col col--6"),children:(0,h.jsx)(g,{item:e})})}function N(e){const{items:s,className:n}=e;if(!s)return(0,h.jsx)(j,{...e});const t=(0,r.d1)(s);return(0,h.jsx)("section",{className:(0,i.A)("row",n),children:t.map((e,s)=>(0,h.jsx)(A,{item:e},s))})}var L=n(7719),_=n(1878),T=n(4267),k=n(594);const y={generatedIndexPage:"generatedIndexPage_vN6x",title:"title_kItE"};function I({categoryGeneratedIndex:e}){return(0,h.jsx)(t.be,{title:e.title,description:e.description,keywords:e.keywords,image:(0,a.Ay)(e.image)})}function C({categoryGeneratedIndex:e}){const s=(0,r.$S)();return(0,h.jsxs)("div",{className:y.generatedIndexPage,children:[(0,h.jsx)(_.A,{}),(0,h.jsx)(k.A,{}),(0,h.jsx)(T.A,{}),(0,h.jsxs)("header",{children:[(0,h.jsx)(u.A,{as:"h1",className:y.title,children:e.title}),e.description&&(0,h.jsx)("p",{children:e.description})]}),(0,h.jsx)("article",{className:"margin-top--lg",children:(0,h.jsx)(N,{items:s.items,className:y.list})}),(0,h.jsx)("footer",{className:"margin-top--md",children:(0,h.jsx)(L.A,{previous:e.navigation.previous,next:e.navigation.next})})]})}function w(e){return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(I,{...e}),(0,h.jsx)(C,{...e})]})}},594:(e,s,n)=>{n.d(s,{A:()=>j});n(6540);var t=n(4164),r=n(7559),a=n(6972),i=n(9169),c=n(8774),l=n(1312),o=n(6025),d=n(4848);function u(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,d.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const m={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function h(){const e=(0,o.Ay)("/");return(0,d.jsx)("li",{className:"breadcrumbs__item",children:(0,d.jsx)(c.A,{"aria-label":(0,l.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,d.jsx)(u,{className:m.breadcrumbHomeIcon})})})}var b=n(5260),x=n(4586);function p(e){const s=function({breadcrumbs:e}){const{siteConfig:s}=(0,x.A)();return{"@context":"https://schema.org","@type":"BreadcrumbList",itemListElement:e.filter(e=>e.href).map((e,n)=>({"@type":"ListItem",position:n+1,name:e.label,item:`${s.url}${e.href}`}))}}({breadcrumbs:e.breadcrumbs});return(0,d.jsx)(b.A,{children:(0,d.jsx)("script",{type:"application/ld+json",children:JSON.stringify(s)})})}const v={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function g({children:e,href:s,isLast:n}){const t="breadcrumbs__link";return n?(0,d.jsx)("span",{className:t,children:e}):s?(0,d.jsx)(c.A,{className:t,href:s,children:(0,d.jsx)("span",{children:e})}):(0,d.jsx)("span",{className:t,children:e})}function f({children:e,active:s}){return(0,d.jsx)("li",{className:(0,t.A)("breadcrumbs__item",{"breadcrumbs__item--active":s}),children:e})}function j(){const e=(0,a.OF)(),s=(0,i.Dt)();return e?(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(p,{breadcrumbs:e}),(0,d.jsx)("nav",{className:(0,t.A)(r.G.docs.docBreadcrumbs,v.breadcrumbsContainer),"aria-label":(0,l.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,d.jsxs)("ul",{className:"breadcrumbs",children:[s&&(0,d.jsx)(h,{}),e.map((s,n)=>{const t=n===e.length-1,r="category"===s.type&&s.linkUnlisted?void 0:s.href;return(0,d.jsx)(f,{active:t,children:(0,d.jsx)(g,{href:r,isLast:t,children:s.label})},n)})]})})]}):null}},1878:(e,s,n)=>{n.d(s,{A:()=>p});n(6540);var t=n(4164),r=n(4586),a=n(8774),i=n(1312),c=n(4070),l=n(7559),o=n(3886),d=n(3025),u=n(4848);const m={unreleased:function({siteTitle:e,versionMetadata:s}){return(0,u.jsx)(i.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:e,versionLabel:(0,u.jsx)("b",{children:s.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function({siteTitle:e,versionMetadata:s}){return(0,u.jsx)(i.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:e,versionLabel:(0,u.jsx)("b",{children:s.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function h(e){const s=m[e.versionMetadata.banner];return(0,u.jsx)(s,{...e})}function b({versionLabel:e,to:s,onClick:n}){return(0,u.jsx)(i.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:e,latestVersionLink:(0,u.jsx)("b",{children:(0,u.jsx)(a.A,{to:s,onClick:n,children:(0,u.jsx)(i.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function x({className:e,versionMetadata:s}){const{siteConfig:{title:n}}=(0,r.A)(),{pluginId:a}=(0,c.vT)({failfast:!0}),{savePreferredVersionName:i}=(0,o.g1)(a),{latestDocSuggestion:d,latestVersionSuggestion:m}=(0,c.HW)(a),x=d??(p=m).docs.find(e=>e.id===p.mainDocId);var p;return(0,u.jsxs)("div",{className:(0,t.A)(e,l.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,u.jsx)("div",{children:(0,u.jsx)(h,{siteTitle:n,versionMetadata:s})}),(0,u.jsx)("div",{className:"margin-top--md",children:(0,u.jsx)(b,{versionLabel:m.label,to:x.path,onClick:()=>i(m.name)})})]})}function p({className:e}){const s=(0,d.r)();return s.banner?(0,u.jsx)(x,{className:e,versionMetadata:s}):null}},4267:(e,s,n)=>{n.d(s,{A:()=>l});n(6540);var t=n(4164),r=n(1312),a=n(7559),i=n(3025),c=n(4848);function l({className:e}){const s=(0,i.r)();return s.badge?(0,c.jsx)("span",{className:(0,t.A)(e,a.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,c.jsx)(r.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:s.label},children:"Version: {versionLabel}"})}):null}},5846:(e,s,n)=>{n.d(s,{W:()=>o});var t=n(6540),r=n(4586);const a=["zero","one","two","few","many","other"];function i(e){return a.filter(s=>e.includes(s))}const c={locale:"en",pluralForms:i(["one","other"]),select:e=>1===e?"one":"other"};function l(){const{i18n:{currentLocale:e}}=(0,r.A)();return(0,t.useMemo)(()=>{try{return function(e){const s=new Intl.PluralRules(e);return{locale:e,pluralForms:i(s.resolvedOptions().pluralCategories),select:e=>s.select(e)}}(e)}catch(s){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${s.message}\n`),c}},[e])}function o(){const e=l();return{selectMessage:(s,n)=>function(e,s,n){const t=e.split("|");if(1===t.length)return t[0];t.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${t.length}: ${e}`);const r=n.select(s),a=n.pluralForms.indexOf(r);return t[Math.min(a,t.length-1)]}(n,s,e)}}},7719:(e,s,n)=>{n.d(s,{A:()=>c});n(6540);var t=n(4164),r=n(1312),a=n(9022),i=n(4848);function c(e){const{className:s,previous:n,next:c}=e;return(0,i.jsxs)("nav",{className:(0,t.A)(s,"pagination-nav"),"aria-label":(0,r.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[n&&(0,i.jsx)(a.A,{...n,subLabel:(0,i.jsx)(r.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),c&&(0,i.jsx)(a.A,{...c,subLabel:(0,i.jsx)(r.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},9022:(e,s,n)=>{n.d(s,{A:()=>i});n(6540);var t=n(4164),r=n(8774),a=n(4848);function i(e){const{permalink:s,title:n,subLabel:i,isNext:c}=e;return(0,a.jsxs)(r.A,{className:(0,t.A)("pagination-nav__link",c?"pagination-nav__link--next":"pagination-nav__link--prev"),to:s,children:[i&&(0,a.jsx)("div",{className:"pagination-nav__sublabel",children:i}),(0,a.jsx)("div",{className:"pagination-nav__label",children:n})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/14eb3368.e9006523.js b/docs/assets/js/14eb3368.e9006523.js deleted file mode 100644 index c72af022..00000000 --- a/docs/assets/js/14eb3368.e9006523.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6969],{477:(e,s,n)=>{n.r(s),n.d(s,{default:()=>w});n(6540);var t=n(5500),r=n(6972),a=n(6025),i=n(4164),c=n(8774),l=n(5846),o=n(6654),d=n(1312),u=n(1107);const m={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var h=n(4848);function b({className:e,href:s,children:n}){return(0,h.jsx)(c.A,{href:s,className:(0,i.A)("card padding--lg",m.cardContainer,e),children:n})}function x({className:e,href:s,icon:n,title:t,description:r}){return(0,h.jsxs)(b,{href:s,className:e,children:[(0,h.jsxs)(u.A,{as:"h2",className:(0,i.A)("text--truncate",m.cardTitle),title:t,children:[n," ",t]}),r&&(0,h.jsx)("p",{className:(0,i.A)("text--truncate",m.cardDescription),title:r,children:r})]})}function p({item:e}){const s=(0,r.Nr)(e),n=function(){const{selectMessage:e}=(0,l.W)();return s=>e(s,(0,d.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:s}))}();return s?(0,h.jsx)(x,{className:e.className,href:s,icon:"\ud83d\uddc3\ufe0f",title:e.label,description:e.description??n(e.items.length)}):null}function v({item:e}){const s=(0,o.A)(e.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",n=(0,r.cC)(e.docId??void 0);return(0,h.jsx)(x,{className:e.className,href:e.href,icon:s,title:e.label,description:e.description??n?.description})}function g({item:e}){switch(e.type){case"link":return(0,h.jsx)(v,{item:e});case"category":return(0,h.jsx)(p,{item:e});default:throw new Error(`unknown item type ${JSON.stringify(e)}`)}}const f={docCardListItem:"docCardListItem_W1sv"};function j({className:e}){const s=(0,r.a4)();return(0,h.jsx)(N,{items:s,className:e})}function A({item:e}){return(0,h.jsx)("article",{className:(0,i.A)(f.docCardListItem,"col col--6"),children:(0,h.jsx)(g,{item:e})})}function N(e){const{items:s,className:n}=e;if(!s)return(0,h.jsx)(j,{...e});const t=(0,r.d1)(s);return(0,h.jsx)("section",{className:(0,i.A)("row",n),children:t.map(((e,s)=>(0,h.jsx)(A,{item:e},s)))})}var L=n(7719),_=n(1878),T=n(4267),k=n(594);const y={generatedIndexPage:"generatedIndexPage_vN6x",title:"title_kItE"};function I({categoryGeneratedIndex:e}){return(0,h.jsx)(t.be,{title:e.title,description:e.description,keywords:e.keywords,image:(0,a.Ay)(e.image)})}function C({categoryGeneratedIndex:e}){const s=(0,r.$S)();return(0,h.jsxs)("div",{className:y.generatedIndexPage,children:[(0,h.jsx)(_.A,{}),(0,h.jsx)(k.A,{}),(0,h.jsx)(T.A,{}),(0,h.jsxs)("header",{children:[(0,h.jsx)(u.A,{as:"h1",className:y.title,children:e.title}),e.description&&(0,h.jsx)("p",{children:e.description})]}),(0,h.jsx)("article",{className:"margin-top--lg",children:(0,h.jsx)(N,{items:s.items,className:y.list})}),(0,h.jsx)("footer",{className:"margin-top--md",children:(0,h.jsx)(L.A,{previous:e.navigation.previous,next:e.navigation.next})})]})}function w(e){return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(I,{...e}),(0,h.jsx)(C,{...e})]})}},594:(e,s,n)=>{n.d(s,{A:()=>j});n(6540);var t=n(4164),r=n(7559),a=n(6972),i=n(9169),c=n(8774),l=n(1312),o=n(6025),d=n(4848);function u(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,d.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const m={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function h(){const e=(0,o.Ay)("/");return(0,d.jsx)("li",{className:"breadcrumbs__item",children:(0,d.jsx)(c.A,{"aria-label":(0,l.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,d.jsx)(u,{className:m.breadcrumbHomeIcon})})})}var b=n(5260),x=n(4586);function p(e){const s=function({breadcrumbs:e}){const{siteConfig:s}=(0,x.A)();return{"@context":"https://schema.org","@type":"BreadcrumbList",itemListElement:e.filter((e=>e.href)).map(((e,n)=>({"@type":"ListItem",position:n+1,name:e.label,item:`${s.url}${e.href}`})))}}({breadcrumbs:e.breadcrumbs});return(0,d.jsx)(b.A,{children:(0,d.jsx)("script",{type:"application/ld+json",children:JSON.stringify(s)})})}const v={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function g({children:e,href:s,isLast:n}){const t="breadcrumbs__link";return n?(0,d.jsx)("span",{className:t,children:e}):s?(0,d.jsx)(c.A,{className:t,href:s,children:(0,d.jsx)("span",{children:e})}):(0,d.jsx)("span",{className:t,children:e})}function f({children:e,active:s}){return(0,d.jsx)("li",{className:(0,t.A)("breadcrumbs__item",{"breadcrumbs__item--active":s}),children:e})}function j(){const e=(0,a.OF)(),s=(0,i.Dt)();return e?(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(p,{breadcrumbs:e}),(0,d.jsx)("nav",{className:(0,t.A)(r.G.docs.docBreadcrumbs,v.breadcrumbsContainer),"aria-label":(0,l.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,d.jsxs)("ul",{className:"breadcrumbs",children:[s&&(0,d.jsx)(h,{}),e.map(((s,n)=>{const t=n===e.length-1,r="category"===s.type&&s.linkUnlisted?void 0:s.href;return(0,d.jsx)(f,{active:t,children:(0,d.jsx)(g,{href:r,isLast:t,children:s.label})},n)}))]})})]}):null}},1878:(e,s,n)=>{n.d(s,{A:()=>p});n(6540);var t=n(4164),r=n(4586),a=n(8774),i=n(1312),c=n(4070),l=n(7559),o=n(3886),d=n(3025),u=n(4848);const m={unreleased:function({siteTitle:e,versionMetadata:s}){return(0,u.jsx)(i.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:e,versionLabel:(0,u.jsx)("b",{children:s.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function({siteTitle:e,versionMetadata:s}){return(0,u.jsx)(i.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:e,versionLabel:(0,u.jsx)("b",{children:s.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function h(e){const s=m[e.versionMetadata.banner];return(0,u.jsx)(s,{...e})}function b({versionLabel:e,to:s,onClick:n}){return(0,u.jsx)(i.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:e,latestVersionLink:(0,u.jsx)("b",{children:(0,u.jsx)(a.A,{to:s,onClick:n,children:(0,u.jsx)(i.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function x({className:e,versionMetadata:s}){const{siteConfig:{title:n}}=(0,r.A)(),{pluginId:a}=(0,c.vT)({failfast:!0}),{savePreferredVersionName:i}=(0,o.g1)(a),{latestDocSuggestion:d,latestVersionSuggestion:m}=(0,c.HW)(a),x=d??(p=m).docs.find((e=>e.id===p.mainDocId));var p;return(0,u.jsxs)("div",{className:(0,t.A)(e,l.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,u.jsx)("div",{children:(0,u.jsx)(h,{siteTitle:n,versionMetadata:s})}),(0,u.jsx)("div",{className:"margin-top--md",children:(0,u.jsx)(b,{versionLabel:m.label,to:x.path,onClick:()=>i(m.name)})})]})}function p({className:e}){const s=(0,d.r)();return s.banner?(0,u.jsx)(x,{className:e,versionMetadata:s}):null}},4267:(e,s,n)=>{n.d(s,{A:()=>l});n(6540);var t=n(4164),r=n(1312),a=n(7559),i=n(3025),c=n(4848);function l({className:e}){const s=(0,i.r)();return s.badge?(0,c.jsx)("span",{className:(0,t.A)(e,a.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,c.jsx)(r.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:s.label},children:"Version: {versionLabel}"})}):null}},5846:(e,s,n)=>{n.d(s,{W:()=>o});var t=n(6540),r=n(4586);const a=["zero","one","two","few","many","other"];function i(e){return a.filter((s=>e.includes(s)))}const c={locale:"en",pluralForms:i(["one","other"]),select:e=>1===e?"one":"other"};function l(){const{i18n:{currentLocale:e}}=(0,r.A)();return(0,t.useMemo)((()=>{try{return function(e){const s=new Intl.PluralRules(e);return{locale:e,pluralForms:i(s.resolvedOptions().pluralCategories),select:e=>s.select(e)}}(e)}catch(s){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${s.message}\n`),c}}),[e])}function o(){const e=l();return{selectMessage:(s,n)=>function(e,s,n){const t=e.split("|");if(1===t.length)return t[0];t.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${t.length}: ${e}`);const r=n.select(s),a=n.pluralForms.indexOf(r);return t[Math.min(a,t.length-1)]}(n,s,e)}}},7719:(e,s,n)=>{n.d(s,{A:()=>c});n(6540);var t=n(4164),r=n(1312),a=n(9022),i=n(4848);function c(e){const{className:s,previous:n,next:c}=e;return(0,i.jsxs)("nav",{className:(0,t.A)(s,"pagination-nav"),"aria-label":(0,r.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[n&&(0,i.jsx)(a.A,{...n,subLabel:(0,i.jsx)(r.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),c&&(0,i.jsx)(a.A,{...c,subLabel:(0,i.jsx)(r.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},9022:(e,s,n)=>{n.d(s,{A:()=>i});n(6540);var t=n(4164),r=n(8774),a=n(4848);function i(e){const{permalink:s,title:n,subLabel:i,isNext:c}=e;return(0,a.jsxs)(r.A,{className:(0,t.A)("pagination-nav__link",c?"pagination-nav__link--next":"pagination-nav__link--prev"),to:s,children:[i&&(0,a.jsx)("div",{className:"pagination-nav__sublabel",children:i}),(0,a.jsx)("div",{className:"pagination-nav__label",children:n})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/176d210f.21c450d1.js b/docs/assets/js/176d210f.21c450d1.js new file mode 100644 index 00000000..8f88edf3 --- /dev/null +++ b/docs/assets/js/176d210f.21c450d1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6100],{73:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-add-features-details-278a519cdfe25bead880d7a18e0b858e.png"},351:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-entity-details-016ab5c5b2fef9f58bde75e6a07c9823.png"},753:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"trufflebox-ui/v1.0.0/userguide","title":"User Manual","description":"This guide covers the complete setup and usage of the Online Feature Store system, including the core services (Online Feature Store and Horizon) and the TruffleBox UI for feature management.","source":"@site/docs/trufflebox-ui/v1.0.0/userguide.md","sourceDirName":"trufflebox-ui/v1.0.0","slug":"/trufflebox-ui/v1.0.0/userguide","permalink":"/BharatMLStack/trufflebox-ui/v1.0.0/userguide","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/trufflebox-ui/v1.0.0/userguide.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"User Manual","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"Trufflebox UI","permalink":"/BharatMLStack/category/trufflebox-ui"},"next":{"title":"SDKs","permalink":"/BharatMLStack/category/sdks"}}');var s=i(4848),t=i(8453);const a={title:"User Manual",sidebar_position:1},o="Usage Guide",l={},c=[{value:"Table of Contents",id:"table-of-contents",level:2},{value:"System Overview",id:"system-overview",level:2},{value:"Environment Setup",id:"environment-setup",level:2},{value:"Online Feature Store Configuration",id:"online-feature-store-configuration",level:3},{value:"Core Application Settings",id:"core-application-settings",level:4},{value:"Storage Configuration",id:"storage-configuration",level:4},{value:"Caching Configuration",id:"caching-configuration",level:4},{value:"Service Discovery and Configuration",id:"service-discovery-and-configuration",level:4},{value:"Horizon Configuration",id:"horizon-configuration",level:3},{value:"Core Application Settings",id:"core-application-settings-1",level:4},{value:"Database Configuration",id:"database-configuration",level:4},{value:"ScyllaDB Configuration",id:"scylladb-configuration",level:4},{value:"Service Integration",id:"service-integration",level:4},{value:"Key Constructs",id:"key-constructs",level:2},{value:"Store ID",id:"store-id",level:3},{value:"Entity",id:"entity",level:3},{value:"Feature Group",id:"feature-group",level:3},{value:"Feature",id:"feature",level:3},{value:"Job",id:"job",level:3},{value:"Configuration Hierarchy",id:"configuration-hierarchy",level:3},{value:"Table of Contents",id:"table-of-contents-1",level:2},{value:"User Flow",id:"user-flow",level:2},{value:"Getting Started with TruffleBox",id:"getting-started-with-trufflebox",level:3},{value:"Authentication",id:"authentication",level:4},{value:"User Management",id:"user-management",level:4},{value:"Navigation",id:"navigation",level:4},{value:"Feature Discovery",id:"feature-discovery",level:3},{value:"Entity Management",id:"entity-management",level:4},{value:"Feature Group Management",id:"feature-group-management",level:4},{value:"Feature Management",id:"feature-management",level:4},{value:"Store Discovery",id:"store-discovery",level:4},{value:"Job Discovery",id:"job-discovery",level:4},{value:"Feature Registry",id:"feature-registry",level:3},{value:"Request Status Tracking",id:"request-status-tracking",level:4},{value:"Step-by-Step Registration Guide",id:"step-by-step-registration-guide",level:4},{value:"Store Registry",id:"store-registry",level:4},{value:"Job Registry",id:"job-registry",level:4},{value:"Entity Registry",id:"entity-registry",level:4},{value:"Feature Group Registry",id:"feature-group-registry",level:4},{value:"Feature Addition",id:"feature-addition",level:4},{value:"Need Help?",id:"need-help",level:4},{value:"Admin Approval Flow",id:"admin-approval-flow",level:2},{value:"Request Management",id:"request-management",level:3},{value:"Viewing All Requests",id:"viewing-all-requests",level:4},{value:"Request Approval Process",id:"request-approval-process",level:4},{value:"Admin Support",id:"admin-support",level:4},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"usage-guide",children:"Usage Guide"})}),"\n",(0,s.jsx)(n.p,{children:"This guide covers the complete setup and usage of the Online Feature Store system, including the core services (Online Feature Store and Horizon) and the TruffleBox UI for feature management."}),"\n",(0,s.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#system-overview",children:"System Overview"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#environment-setup",children:"Environment Setup"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#online-feature-store-configuration",children:"Online Feature Store Configuration"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#horizon-configuration",children:"Horizon Configuration"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#key-constructs",children:"Key Constructs"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#trufflebox-ui-guide",children:"TruffleBox UI Guide"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#user-flow",children:"User Flow"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#admin-approval-flow",children:"Admin Approval Flow"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"system-overview",children:"System Overview"}),"\n",(0,s.jsx)(n.p,{children:"The Online Feature Store is a comprehensive feature management system consisting of two main components:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Online Feature Store"}),": The core feature serving service that provides real-time feature retrieval with multiple storage backends and caching layers"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Horizon"}),": The configuration and metadata management service that handles feature definitions, stores, and job configurations"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"These services work together to provide a scalable, high-performance feature store for machine learning applications."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"environment-setup",children:"Environment Setup"}),"\n",(0,s.jsx)(n.h3,{id:"online-feature-store-configuration",children:"Online Feature Store Configuration"}),"\n",(0,s.jsx)(n.p,{children:"The Online Feature Store requires several environment variables to configure storage backends, caching, and service settings."}),"\n",(0,s.jsx)(n.h4,{id:"core-application-settings",children:"Core Application Settings"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"APP_ENV=prod\nAPP_LOG_LEVEL=DEBUG\nAPP_METRIC_SAMPLING_RATE=1\nAPP_NAME=online-feature-store\nAPP_PORT=8005\nAUTH_TOKEN=ofs-token\n"})}),"\n",(0,s.jsx)(n.h4,{id:"storage-configuration",children:"Storage Configuration"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"ScyllaDB Storage (Primary Storage)"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# Primary ScyllaDB cluster\nSTORAGE_SCYLLA_1_CONTACT_POINTS=localhost\nSTORAGE_SCYLLA_1_KEYSPACE=ofs\nSTORAGE_SCYLLA_1_NUM_CONNS=1\nSTORAGE_SCYLLA_1_PORT=9042\nSTORAGE_SCYLLA_1_TIMEOUT_IN_MS=300000\nSTORAGE_SCYLLA_1_PASSWORD=\nSTORAGE_SCYLLA_1_USERNAME=ofs\n\n# Secondary ScyllaDB cluster\nSTORAGE_SCYLLA_5_CONTACT_POINTS=localhost\nSTORAGE_SCYLLA_5_KEYSPACE=onfs\nSTORAGE_SCYLLA_5_NUM_CONNS=1\nSTORAGE_SCYLLA_5_PASSWORD=\nSTORAGE_SCYLLA_5_PORT=9042\nSTORAGE_SCYLLA_5_TIMEOUT_IN_MS=300000\nSTORAGE_SCYLLA_5_USERNAME=\n\n# Active ScyllaDB configurations\nSTORAGE_SCYLLA_ACTIVE_CONFIG_IDS=1,5\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Redis Storage Configuration"})}),"\n",(0,s.jsx)(n.p,{children:"Redis serves dual purposes in the Online Feature Store:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Primary Storage Backend"}),": For fast feature retrieval and storage"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Distributed Cache Layer"}),": For improved performance and reduced latency"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Redis configurations can be referenced by their IDs in Store configurations, similar to ScyllaDB. Each Redis configuration can be independently used as either a storage backend or cache layer."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# Redis Failover Configuration 1 (ID: 2)\nSTORAGE_REDIS_FAILOVER_2_SENTINEL_ADDRESSES=localhost:26379\nSTORAGE_REDIS_FAILOVER_2_DB=0\nSTORAGE_REDIS_FAILOVER_2_DISABLE_IDENTITY=true\nSTORAGE_REDIS_FAILOVER_2_MASTER_NAME=mymaster\nSTORAGE_REDIS_FAILOVER_2_MAX_IDLE_CONN=32\nSTORAGE_REDIS_FAILOVER_2_MIN_IDLE_CONN=20\nSTORAGE_REDIS_FAILOVER_2_MAX_ACTIVE_CONN=32\nSTORAGE_REDIS_FAILOVER_2_MAX_RETRY=-1\nSTORAGE_REDIS_FAILOVER_2_POOL_FIFO=false\nSTORAGE_REDIS_FAILOVER_2_READ_TIMEOUT_IN_MS=3000\nSTORAGE_REDIS_FAILOVER_2_WRITE_TIMEOUT_IN_MS=3000\nSTORAGE_REDIS_FAILOVER_2_POOL_TIMEOUT_IN_MS=3000\nSTORAGE_REDIS_FAILOVER_2_POOL_SIZE=32\nSTORAGE_REDIS_FAILOVER_2_CONN_MAX_IDLE_TIMEOUT_IN_MINUTES=15\nSTORAGE_REDIS_FAILOVER_2_CONN_MAX_AGE_IN_MINUTES=30\n\n# Redis Failover Configuration 2 (ID: 4)\nSTORAGE_REDIS_FAILOVER_4_SENTINEL_ADDRESSES=localhost:26379\nSTORAGE_REDIS_FAILOVER_4_DB=0\nSTORAGE_REDIS_FAILOVER_4_DISABLE_IDENTITY=true\nSTORAGE_REDIS_FAILOVER_4_MASTER_NAME=mymaster\nSTORAGE_REDIS_FAILOVER_4_MAX_IDLE_CONN=32\nSTORAGE_REDIS_FAILOVER_4_MIN_IDLE_CONN=20\nSTORAGE_REDIS_FAILOVER_4_MAX_ACTIVE_CONN=32\nSTORAGE_REDIS_FAILOVER_4_MAX_RETRY=-1\nSTORAGE_REDIS_FAILOVER_4_POOL_FIFO=false\nSTORAGE_REDIS_FAILOVER_4_READ_TIMEOUT_IN_MS=3000\nSTORAGE_REDIS_FAILOVER_4_WRITE_TIMEOUT_IN_MS=3000\nSTORAGE_REDIS_FAILOVER_4_POOL_TIMEOUT_IN_MS=3000\nSTORAGE_REDIS_FAILOVER_4_POOL_SIZE=32\nSTORAGE_REDIS_FAILOVER_4_CONN_MAX_IDLE_TIMEOUT_IN_MINUTES=15\nSTORAGE_REDIS_FAILOVER_4_CONN_MAX_AGE_IN_MINUTES=30\n\n# High-Performance Redis Configuration (ID: 6)\nSTORAGE_REDIS_FAILOVER_6_CONN_MAX_AGE_IN_MINUTES=-1\nSTORAGE_REDIS_FAILOVER_6_CONN_MAX_IDLE_TIMEOUT_IN_MINUTES=30\nSTORAGE_REDIS_FAILOVER_6_DB=0\nSTORAGE_REDIS_FAILOVER_6_DISABLE_IDENTITY=true\nSTORAGE_REDIS_FAILOVER_6_MASTER_NAME=mymaster\nSTORAGE_REDIS_FAILOVER_6_MAX_ACTIVE_CONN=202\nSTORAGE_REDIS_FAILOVER_6_MAX_IDLE_CONN=157\nSTORAGE_REDIS_FAILOVER_6_MAX_RETRY=-1\nSTORAGE_REDIS_FAILOVER_6_MIN_IDLE_CONN=52\nSTORAGE_REDIS_FAILOVER_6_PASSWORD=\nSTORAGE_REDIS_FAILOVER_6_POOL_FIFO=false\nSTORAGE_REDIS_FAILOVER_6_POOL_SIZE=202\nSTORAGE_REDIS_FAILOVER_6_POOL_TIMEOUT_IN_MS=2\nSTORAGE_REDIS_FAILOVER_6_READ_TIMEOUT_IN_MS=75\nSTORAGE_REDIS_FAILOVER_6_ROUTE_RANDOM=true\nSTORAGE_REDIS_FAILOVER_6_SENTINEL_ADDRESSES=localhost:26379\nSTORAGE_REDIS_FAILOVER_6_WRITE_TIMEOUT_IN_MS=300\n\n# Active Redis configurations\nSTORAGE_REDIS_FAILOVER_ACTIVE_CONFIG_IDS=2,4,6\n"})}),"\n",(0,s.jsx)(n.h4,{id:"caching-configuration",children:"Caching Configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# In-Memory Cache\nIN_MEM_CACHE_3_ENABLED=true\nIN_MEM_CACHE_3_NAME=onfs\nIN_MEM_CACHE_3_SIZE_IN_BYTES=10000000\nIN_MEM_CACHE_ACTIVE_CONFIG_IDS=3\n\n# Distributed Cache (uses Redis configurations)\n# Redis configurations (IDs: 2,4,6) can be used for distributed caching\nDISTRIBUTED_CACHE_CONF_IDS=2\n"})}),"\n",(0,s.jsx)(n.h4,{id:"service-discovery-and-configuration",children:"Service Discovery and Configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# ETCD Configuration for service discovery\nETCD_SERVER=0.0.0.0:2379\nETCD_WATCHER_ENABLED=true\n"})}),"\n",(0,s.jsx)(n.h3,{id:"horizon-configuration",children:"Horizon Configuration"}),"\n",(0,s.jsx)(n.p,{children:"Horizon manages the metadata and configuration for the Online Feature Store system."}),"\n",(0,s.jsx)(n.h4,{id:"core-application-settings-1",children:"Core Application Settings"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"APP_NAME=horizon\nAPP_ENVIRONMENT=PROD\nAPP_ENV=production\nAPP_PORT=8082\nAPP_LOG_LEVEL=DEBUG\nAPP_METRIC_SAMPLING_RATE=1\nAPP_GC_PERCENTAGE=1\n"})}),"\n",(0,s.jsx)(n.h4,{id:"database-configuration",children:"Database Configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# MySQL Master Configuration\nMYSQL_MASTER_MAX_POOL_SIZE=5\nMYSQL_MASTER_MIN_POOL_SIZE=2\nMYSQL_MASTER_PASSWORD=\nMYSQL_MASTER_HOST=127.0.0.1\nMYSQL_MASTER_PORT=3306\nMYSQL_DB_NAME=ml_config\nMYSQL_MASTER_USERNAME=root\n\n# MySQL Slave Configuration\nMYSQL_SLAVE_MAX_POOL_SIZE=5\nMYSQL_SLAVE_MIN_POOL_SIZE=2\nMYSQL_SLAVE_PASSWORD=\nMYSQL_SLAVE_HOST=127.0.0.1\nMYSQL_SLAVE_USERNAME=root\nMYSQL_SLAVE_PORT=3306\n"})}),"\n",(0,s.jsx)(n.h4,{id:"scylladb-configuration",children:"ScyllaDB Configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# ScyllaDB for Horizon\nSCYLLA_1_CONTACT_POINTS=localhost\nSCYLLA_1_KEYSPACE=onfs\nSCYLLA_1_NUM_CONNS=1\nSCYLLA_1_PORT=9042\nSCYLLA_1_TIMEOUT_IN_MS=300000\nSCYLLA_1_PASSWORD=\nSCYLLA_1_USERNAME=\nSCYLLA_ACTIVE_CONFIG_IDS=1\n"})}),"\n",(0,s.jsx)(n.h4,{id:"service-integration",children:"Service Integration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# ETCD Configuration\nETCD_WATCHER_ENABLED=true\nETCD_SERVER=localhost:2379\n\n# Integration with Online Feature Store\nONLINE_FEATURE_STORE_APP_NAME=online-feature-store\n"})}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"key-constructs",children:"Key Constructs"}),"\n",(0,s.jsx)(n.p,{children:"Understanding these key constructs is essential for effectively using the Online Feature Store:"}),"\n",(0,s.jsx)(n.h3,{id:"store-id",children:"Store ID"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"Store ID"})," is a unique identifier that represents a data storage configuration within the system. It defines:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Storage Backend"}),": Which underlying storage system (ScyllaDB, Redis, etc.) to use"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Configuration Parameters"}),": Connection settings, timeouts, pool sizes"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Access Patterns"}),": How data is read from and written to the store"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Store IDs are referenced throughout the system to:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Route feature requests to the appropriate storage backend"}),"\n",(0,s.jsx)(n.li,{children:"Apply specific caching strategies"}),"\n",(0,s.jsx)(n.li,{children:"Manage data lifecycle and retention policies"}),"\n",(0,s.jsx)(n.li,{children:"Configure stores in TruffleBox UI for feature groups and entities"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Storage Backend Configuration:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"ScyllaDB Store IDs"}),": ",(0,s.jsx)(n.code,{children:"STORAGE_SCYLLA_ACTIVE_CONFIG_IDS=1,5"})," indicates ScyllaDB configurations with IDs 1 and 5 are active"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Redis Store IDs"}),": ",(0,s.jsx)(n.code,{children:"STORAGE_REDIS_FAILOVER_ACTIVE_CONFIG_IDS=2,4,6"})," indicates Redis configurations with IDs 2, 4, and 6 are active"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Dual Usage of Redis:"}),"\nRedis configurations can serve dual purposes:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"As Storage Backend"}),": Redis IDs (2,4,6) can be configured as primary storage in Store configurations"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"As Distributed Cache"}),": Same Redis IDs can be used for caching via ",(0,s.jsx)(n.code,{children:"DISTRIBUTED_CACHE_CONF_IDS=2"})]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"When creating stores in TruffleBox, you can reference these storage configuration IDs to determine which backend (ScyllaDB ID 1/5 or Redis ID 2/4/6) will be used for your feature data."}),"\n",(0,s.jsx)(n.h3,{id:"entity",children:"Entity"}),"\n",(0,s.jsxs)(n.p,{children:["An ",(0,s.jsx)(n.strong,{children:"Entity"})," represents a logical grouping of related features, typically corresponding to a business object (e.g., User, Product, Transaction). Entities provide:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Namespace"}),": Logical separation of feature groups"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Identity"}),": Primary key definition for feature lookup"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Configuration"}),": Cache settings and storage preferences"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"feature-group",children:"Feature Group"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"Feature Group"})," is a collection of related features that share:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Common Entity"}),": All features belong to the same entity"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Storage Configuration"}),": Same underlying storage and caching strategy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Data Lifecycle"}),": Shared TTL and retention policies"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Access Patterns"}),": Similar read/write characteristics"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"feature",children:"Feature"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"Feature"})," is an individual data point that can be retrieved for machine learning models. Each feature has:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Name"}),": Unique identifier within its feature group"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Data Type"}),": The type of data stored (string, integer, float, etc.)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Default Value"}),": Value returned when feature data is not available"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Source Mapping"}),": How the feature maps to underlying storage columns"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"job",children:"Job"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"Job"})," represents a data processing pipeline that:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Ingests Data"}),": Processes raw data from various sources"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Transforms Features"}),": Applies business logic and computations"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Updates Storage"}),": Writes processed features to the feature store"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Scheduling"}),": Defines when and how often the job runs"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"configuration-hierarchy",children:"Configuration Hierarchy"}),"\n",(0,s.jsx)(n.p,{children:"The system uses a hierarchical configuration approach:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"Store \u2192 Entity \u2192 Feature Group \u2192 Feature\n \u2193 \u2193 \u2193 \u2193\nConfig Identity Collection Individual\nLevel Level Level Level\n"})}),"\n",(0,s.jsx)(n.p,{children:"This hierarchy allows for:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Inheritance"}),": Lower levels inherit settings from higher levels"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Override"}),": Specific configurations can be overridden at each level"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Flexibility"}),": Different storage strategies for different use cases"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h1,{id:"trufflebox-ui-guide",children:"TruffleBox UI Guide"}),"\n",(0,s.jsx)(n.p,{children:"TruffleBox is a comprehensive and intuitive UI to help users onboard new features, models and related entities easily. We will build iteratively and add support overtime for entire feature lifecycle management."}),"\n",(0,s.jsx)(n.h2,{id:"table-of-contents-1",children:"Table of Contents"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#user-flow",children:"User Flow"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#getting-started-with-trufflebox",children:"Getting Started with TruffleBox"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#feature-discovery",children:"Feature Discovery"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#feature-registry",children:"Feature Registry"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#admin-approval-flow",children:"Admin Approval Flow"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#request-management",children:"Request Management"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"user-flow",children:"User Flow"}),"\n",(0,s.jsx)(n.h3,{id:"getting-started-with-trufflebox",children:"Getting Started with TruffleBox"}),"\n",(0,s.jsx)(n.h4,{id:"authentication",children:"Authentication"}),"\n",(0,s.jsx)(n.p,{children:"Users can access TruffleBox through registration or login:"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Registration"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"New users should fill in all details and click Register."}),"\n",(0,s.jsx)(n.li,{children:"Once Registered, Please wait for an admin to activate your User"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Registration Screen",src:i(7184).A+"",width:"3438",height:"1690"})}),"\n",(0,s.jsx)(n.h4,{id:"user-management",children:"User Management"}),"\n",(0,s.jsx)(n.p,{children:"Admin users can manage other users through the User Management interface:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"User Management",src:i(8224).A+"",width:"3398",height:"1676"})}),"\n",(0,s.jsx)(n.p,{children:"In the User Management page, admins can:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"View all registered users"}),"\n",(0,s.jsx)(n.li,{children:"Activate/deactivate user accounts"}),"\n",(0,s.jsx)(n.li,{children:"Modify user roles"}),"\n",(0,s.jsx)(n.li,{children:"Manage user permissions"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This is a crucial step in the user onboarding process as new users must be activated by an admin before they can log in to the system."}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Login"}),": Existing users can login with their registered email and password."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Login Screen",src:i(3620).A+"",width:"3438",height:"1690"})}),"\n",(0,s.jsx)(n.h4,{id:"navigation",children:"Navigation"}),"\n",(0,s.jsx)(n.p,{children:"After logging in, you'll be redirected to the feature-discovery page. Access the Control Center by clicking the hamburger icon in the top left corner."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Control Center Navigation",src:i(4525).A+"",width:"3450",height:"1700"})}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"feature-discovery",children:"Feature Discovery"}),"\n",(0,s.jsx)(n.p,{children:"The Feature Discovery page displays approved entities, feature groups, and features."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Feature Discovery Landing Page",src:i(2904).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"You can:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"View details by clicking the info icon"}),"\n",(0,s.jsx)(n.li,{children:"Edit entities, feature groups, and features as needed"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"entity-management",children:"Entity Management"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Entity Details",src:i(2399).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:'View entity details and edit them (limited to In Memory Cache and Distributed Cache details excluding config ID). Submit changes via "Save Changes" to raise an edit request.'}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Edit Entity",src:i(911).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.h4,{id:"feature-group-management",children:"Feature Group Management"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Feature Group Details",src:i(7035).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"Edit feature groups (TTL, In-Memory Cache Enabled, Distributed Cache Enabled, Layout Version) and submit changes to raise an edit request."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Edit Feature Group",src:i(3963).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.h4,{id:"feature-management",children:"Feature Management"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Feature Details",src:i(6092).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"Edit features (Default Value, Source Base Path, Source Data Column, Storage Provider) and submit changes to raise an edit request."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Edit Features",src:i(7943).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.h4,{id:"store-discovery",children:"Store Discovery"}),"\n",(0,s.jsx)(n.p,{children:"Access Store Discovery from the Control Center to view all stores in the database."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Store Discovery",src:i(8689).A+"",width:"3456",height:"1680"})}),"\n",(0,s.jsx)(n.p,{children:"You can search for specific stores but have view-only access."}),"\n",(0,s.jsx)(n.h4,{id:"job-discovery",children:"Job Discovery"}),"\n",(0,s.jsx)(n.p,{children:"Access Job Discovery from the Control Center to view all jobs in the database."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Job Discovery",src:i(9095).A+"",width:"3456",height:"1680"})}),"\n",(0,s.jsx)(n.p,{children:"You can search for specific jobs but have view-only access."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"feature-registry",children:"Feature Registry"}),"\n",(0,s.jsx)(n.p,{children:"In the Control Center, find the 'Feature Registry' accordion to access various registry options for component registration."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Feature Registry Accordion",src:i(4525).A+"",width:"3450",height:"1700"})}),"\n",(0,s.jsx)(n.h4,{id:"request-status-tracking",children:"Request Status Tracking"}),"\n",(0,s.jsx)(n.p,{children:"After raising a request, track its status in the respective registry page. For rejected requests, view the rejection reason by clicking the info icon in the Actions column."}),"\n",(0,s.jsx)(n.h4,{id:"step-by-step-registration-guide",children:"Step-by-Step Registration Guide"}),"\n",(0,s.jsx)(n.p,{children:"For proper feature lifecycle management, register components in this order:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Store"}),"\n",(0,s.jsx)(n.li,{children:"Job"}),"\n",(0,s.jsx)(n.li,{children:"Entity"}),"\n",(0,s.jsx)(n.li,{children:"Feature Group"}),"\n",(0,s.jsx)(n.li,{children:"Features (if not added during Feature Group registration)"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"store-registry",children:"Store Registry"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Register Store",src:i(1644).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"Access Store Registry from the Control Center to view raised requests and register new stores. Fill required data and submit to raise a request."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Store Details",src:i(1481).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Important Considerations:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Always add primary keys for proper data identification"}),"\n",(0,s.jsx)(n.li,{children:"Accurate store configuration is crucial as changes later can be complex"}),"\n",(0,s.jsx)(n.li,{children:"Admin approval creates a database table with your configuration"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"job-registry",children:"Job Registry"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Create Job",src:i(3366).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"Access Job Registry from the Control Center to view raised requests and create new jobs. Fill required data and submit your request."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Job Details",src:i(2791).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"Ensure job details are accurate before proceeding to Entity Registry."}),"\n",(0,s.jsx)(n.h4,{id:"entity-registry",children:"Entity Registry"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Create Entity",src:i(9214).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"Access Entity Registry from the Control Center to view raised requests and create new entities. Fill required data and submit your request."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Entity Detail View",src:i(351).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Important Considerations:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Ensure entity details align with your data model"}),"\n",(0,s.jsx)(n.li,{children:"The entity serves as a logical container for feature groups"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"feature-group-registry",children:"Feature Group Registry"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Create Feature Group",src:i(1954).A+"",width:"3456",height:"1680"})}),"\n",(0,s.jsx)(n.p,{children:"Access Feature Group Registry from the Control Center to view raised requests and create new feature groups. Fill required data and submit your request."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Feature Group Detail View",src:i(2955).A+"",width:"3456",height:"1680"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Important Considerations:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Primary keys must match the store primary keys"}),"\n",(0,s.jsx)(n.li,{children:"TTL settings determine how long feature data is stored"}),"\n",(0,s.jsx)(n.li,{children:"Configure cache settings based on access patterns"}),"\n",(0,s.jsx)(n.li,{children:"Approved feature groups automatically add necessary columns to the database table"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"feature-addition",children:"Feature Addition"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Add Features",src:i(3532).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"Access Feature Addition from the Control Center to view raised requests and add new features. Fill required data and submit your request."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Feature Detail View",src:i(73).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Important Considerations:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Ensure feature data types are compatible with source data"}),"\n",(0,s.jsx)(n.li,{children:"Set appropriate default values and correct source data column mapping"}),"\n",(0,s.jsx)(n.li,{children:"Approved features automatically add columns to the database table"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"need-help",children:"Need Help?"}),"\n",(0,s.jsx)(n.p,{children:"Please reach out to the BharatMLStack core team for any questions about using TruffleBox."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"admin-approval-flow",children:"Admin Approval Flow"}),"\n",(0,s.jsx)(n.p,{children:"As an admin, you're responsible for reviewing and managing user requests."}),"\n",(0,s.jsx)(n.h3,{id:"request-management",children:"Request Management"}),"\n",(0,s.jsx)(n.h4,{id:"viewing-all-requests",children:"Viewing All Requests"}),"\n",(0,s.jsx)(n.p,{children:"After logging in as an admin, you can see all pending requests across different components (Stores, Jobs, Entities, Feature Groups, Features)."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Admin Dashboard",src:i(6500).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.h4,{id:"request-approval-process",children:"Request Approval Process"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Review Details"}),": Click the info icon to view complete request details"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Request Details",src:i(6500).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Approval Option"}),": After review, use the approve/reject buttons"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Approval Buttons",src:i(6500).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Approval Process"}),":",(0,s.jsx)(n.br,{}),"\n",'Click "Approve" to process the request. The system will create database tables or add columns as needed. A success message confirms completion.']}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Approval Success",src:i(6500).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Rejection Process"}),":",(0,s.jsx)(n.br,{}),"\n",'Click "Reject" to deny a request. Provide a rejection reason to help users understand why their request wasn\'t approved.']}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Rejection Reason",src:i(6863).A+"",width:"3456",height:"1680"})}),"\n",(0,s.jsx)(n.p,{children:"Users can view the rejection reason in their respective registry page."}),"\n",(0,s.jsx)(n.h4,{id:"admin-support",children:"Admin Support"}),"\n",(0,s.jsx)(n.p,{children:"If you need assistance with admin functions, please contact the BharatMLStack core team."}),"\n",(0,s.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,s.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,s.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\ud83d\udcac ",(0,s.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,s.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,s.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,s.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,s.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,s.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,s.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,s.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)("div",{align:"center",children:(0,s.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,s.jsx)("div",{align:"center",children:(0,s.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},911:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-edit-entity-0c3bb1263b53ed678ae2f9310441f3d7.png"},1481:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-store-details-a36537beae9ac91576186b193e858112.png"},1644:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-store-d6f80ceb9a6570b225bba4653ac22dd8.png"},1954:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-fg-9c3b22e62b389f2c1baf968a6e201964.png"},2399:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-feature-discovery-entity-details-839bb44b2cd99129eeb0ee785d19152c.png"},2791:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-job-details-075436efba1df107ac7e42164ff6494a.png"},2904:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-feature-discovery-c3a8456bb04479842666120a0ec082e6.png"},2955:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-fg-details-1b1100bbb5d23fac31414b15f2a59366.png"},3366:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-job-e45c350f42a09adaeea50ef00d53df55.png"},3532:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-add-features-6cb39960d91af3ee1c896492188cfcb5.png"},3620:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-login-de1cbf15b2daa5c532875a94a4ad1a47.png"},3963:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-edit-fg-edc1a8999700e5c1e9ff023fe9f6413f.png"},4525:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-navigation-0e472fd13ccdae9448011eb9aebb990e.png"},6092:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-feature-discovery-feature-details-b780eb1ede246eb257862a46f0fdb53e.png"},6500:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-approve-store-1057c0853f92becfa9b1f87d165a72f9.png"},6863:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-reject-popup-9941183f1128e19034f41970d218d72f.png"},7035:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-feature-discovery-fg-details-a2dda4f72568878138e3b2d50fa20e8f.png"},7184:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-registration-aed7738afc652b6418bdc00966850ec0.png"},7943:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-edit-features-41cb78c09d70203c166fce91976d2ba0.png"},8224:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-user-management-2c50fa8488f21ff07b9925c48a10f7cd.png"},8453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>o});var r=i(6540);const s={},t=r.createContext(s);function a(e){const n=r.useContext(t);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(t.Provider,{value:n},e.children)}},8689:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-store-discovery-8c9042352255fff36b35b4aa193583f7.png"},9095:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-job-discovery-3fac78c4b09b6c76a7bc1dd0738cc93d.png"},9214:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-entity-fe6449f47304e0377107d8e5b3ce1d30.png"}}]); \ No newline at end of file diff --git a/docs/assets/js/176d210f.47d21595.js b/docs/assets/js/176d210f.47d21595.js deleted file mode 100644 index 239e1e8f..00000000 --- a/docs/assets/js/176d210f.47d21595.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6100],{239:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-job-e45c350f42a09adaeea50ef00d53df55.png"},598:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-feature-discovery-fg-details-a2dda4f72568878138e3b2d50fa20e8f.png"},753:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"trufflebox-ui/v1.0.0/userguide","title":"User Manual","description":"This guide covers the complete setup and usage of the Online Feature Store system, including the core services (Online Feature Store and Horizon) and the TruffleBox UI for feature management.","source":"@site/docs/trufflebox-ui/v1.0.0/userguide.md","sourceDirName":"trufflebox-ui/v1.0.0","slug":"/trufflebox-ui/v1.0.0/userguide","permalink":"/BharatMLStack/trufflebox-ui/v1.0.0/userguide","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/trufflebox-ui/v1.0.0/userguide.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"User Manual","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"Trufflebox UI","permalink":"/BharatMLStack/category/trufflebox-ui"},"next":{"title":"SDKs","permalink":"/BharatMLStack/category/sdks"}}');var s=i(4848),t=i(8453);const a={title:"User Manual",sidebar_position:1},o="Usage Guide",l={},c=[{value:"Table of Contents",id:"table-of-contents",level:2},{value:"System Overview",id:"system-overview",level:2},{value:"Environment Setup",id:"environment-setup",level:2},{value:"Online Feature Store Configuration",id:"online-feature-store-configuration",level:3},{value:"Core Application Settings",id:"core-application-settings",level:4},{value:"Storage Configuration",id:"storage-configuration",level:4},{value:"Caching Configuration",id:"caching-configuration",level:4},{value:"Service Discovery and Configuration",id:"service-discovery-and-configuration",level:4},{value:"Horizon Configuration",id:"horizon-configuration",level:3},{value:"Core Application Settings",id:"core-application-settings-1",level:4},{value:"Database Configuration",id:"database-configuration",level:4},{value:"ScyllaDB Configuration",id:"scylladb-configuration",level:4},{value:"Service Integration",id:"service-integration",level:4},{value:"Key Constructs",id:"key-constructs",level:2},{value:"Store ID",id:"store-id",level:3},{value:"Entity",id:"entity",level:3},{value:"Feature Group",id:"feature-group",level:3},{value:"Feature",id:"feature",level:3},{value:"Job",id:"job",level:3},{value:"Configuration Hierarchy",id:"configuration-hierarchy",level:3},{value:"Table of Contents",id:"table-of-contents-1",level:2},{value:"User Flow",id:"user-flow",level:2},{value:"Getting Started with TruffleBox",id:"getting-started-with-trufflebox",level:3},{value:"Authentication",id:"authentication",level:4},{value:"User Management",id:"user-management",level:4},{value:"Navigation",id:"navigation",level:4},{value:"Feature Discovery",id:"feature-discovery",level:3},{value:"Entity Management",id:"entity-management",level:4},{value:"Feature Group Management",id:"feature-group-management",level:4},{value:"Feature Management",id:"feature-management",level:4},{value:"Store Discovery",id:"store-discovery",level:4},{value:"Job Discovery",id:"job-discovery",level:4},{value:"Feature Registry",id:"feature-registry",level:3},{value:"Request Status Tracking",id:"request-status-tracking",level:4},{value:"Step-by-Step Registration Guide",id:"step-by-step-registration-guide",level:4},{value:"Store Registry",id:"store-registry",level:4},{value:"Job Registry",id:"job-registry",level:4},{value:"Entity Registry",id:"entity-registry",level:4},{value:"Feature Group Registry",id:"feature-group-registry",level:4},{value:"Feature Addition",id:"feature-addition",level:4},{value:"Need Help?",id:"need-help",level:4},{value:"Admin Approval Flow",id:"admin-approval-flow",level:2},{value:"Request Management",id:"request-management",level:3},{value:"Viewing All Requests",id:"viewing-all-requests",level:4},{value:"Request Approval Process",id:"request-approval-process",level:4},{value:"Admin Support",id:"admin-support",level:4},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"usage-guide",children:"Usage Guide"})}),"\n",(0,s.jsx)(n.p,{children:"This guide covers the complete setup and usage of the Online Feature Store system, including the core services (Online Feature Store and Horizon) and the TruffleBox UI for feature management."}),"\n",(0,s.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#system-overview",children:"System Overview"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#environment-setup",children:"Environment Setup"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#online-feature-store-configuration",children:"Online Feature Store Configuration"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#horizon-configuration",children:"Horizon Configuration"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#key-constructs",children:"Key Constructs"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#trufflebox-ui-guide",children:"TruffleBox UI Guide"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#user-flow",children:"User Flow"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#admin-approval-flow",children:"Admin Approval Flow"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"system-overview",children:"System Overview"}),"\n",(0,s.jsx)(n.p,{children:"The Online Feature Store is a comprehensive feature management system consisting of two main components:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Online Feature Store"}),": The core feature serving service that provides real-time feature retrieval with multiple storage backends and caching layers"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Horizon"}),": The configuration and metadata management service that handles feature definitions, stores, and job configurations"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"These services work together to provide a scalable, high-performance feature store for machine learning applications."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"environment-setup",children:"Environment Setup"}),"\n",(0,s.jsx)(n.h3,{id:"online-feature-store-configuration",children:"Online Feature Store Configuration"}),"\n",(0,s.jsx)(n.p,{children:"The Online Feature Store requires several environment variables to configure storage backends, caching, and service settings."}),"\n",(0,s.jsx)(n.h4,{id:"core-application-settings",children:"Core Application Settings"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"APP_ENV=prod\nAPP_LOG_LEVEL=DEBUG\nAPP_METRIC_SAMPLING_RATE=1\nAPP_NAME=online-feature-store\nAPP_PORT=8005\nAUTH_TOKEN=ofs-token\n"})}),"\n",(0,s.jsx)(n.h4,{id:"storage-configuration",children:"Storage Configuration"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"ScyllaDB Storage (Primary Storage)"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# Primary ScyllaDB cluster\nSTORAGE_SCYLLA_1_CONTACT_POINTS=localhost\nSTORAGE_SCYLLA_1_KEYSPACE=ofs\nSTORAGE_SCYLLA_1_NUM_CONNS=1\nSTORAGE_SCYLLA_1_PORT=9042\nSTORAGE_SCYLLA_1_TIMEOUT_IN_MS=300000\nSTORAGE_SCYLLA_1_PASSWORD=\nSTORAGE_SCYLLA_1_USERNAME=ofs\n\n# Secondary ScyllaDB cluster\nSTORAGE_SCYLLA_5_CONTACT_POINTS=localhost\nSTORAGE_SCYLLA_5_KEYSPACE=onfs\nSTORAGE_SCYLLA_5_NUM_CONNS=1\nSTORAGE_SCYLLA_5_PASSWORD=\nSTORAGE_SCYLLA_5_PORT=9042\nSTORAGE_SCYLLA_5_TIMEOUT_IN_MS=300000\nSTORAGE_SCYLLA_5_USERNAME=\n\n# Active ScyllaDB configurations\nSTORAGE_SCYLLA_ACTIVE_CONFIG_IDS=1,5\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Redis Storage Configuration"})}),"\n",(0,s.jsx)(n.p,{children:"Redis serves dual purposes in the Online Feature Store:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Primary Storage Backend"}),": For fast feature retrieval and storage"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Distributed Cache Layer"}),": For improved performance and reduced latency"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Redis configurations can be referenced by their IDs in Store configurations, similar to ScyllaDB. Each Redis configuration can be independently used as either a storage backend or cache layer."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# Redis Failover Configuration 1 (ID: 2)\nSTORAGE_REDIS_FAILOVER_2_SENTINEL_ADDRESSES=localhost:26379\nSTORAGE_REDIS_FAILOVER_2_DB=0\nSTORAGE_REDIS_FAILOVER_2_DISABLE_IDENTITY=true\nSTORAGE_REDIS_FAILOVER_2_MASTER_NAME=mymaster\nSTORAGE_REDIS_FAILOVER_2_MAX_IDLE_CONN=32\nSTORAGE_REDIS_FAILOVER_2_MIN_IDLE_CONN=20\nSTORAGE_REDIS_FAILOVER_2_MAX_ACTIVE_CONN=32\nSTORAGE_REDIS_FAILOVER_2_MAX_RETRY=-1\nSTORAGE_REDIS_FAILOVER_2_POOL_FIFO=false\nSTORAGE_REDIS_FAILOVER_2_READ_TIMEOUT_IN_MS=3000\nSTORAGE_REDIS_FAILOVER_2_WRITE_TIMEOUT_IN_MS=3000\nSTORAGE_REDIS_FAILOVER_2_POOL_TIMEOUT_IN_MS=3000\nSTORAGE_REDIS_FAILOVER_2_POOL_SIZE=32\nSTORAGE_REDIS_FAILOVER_2_CONN_MAX_IDLE_TIMEOUT_IN_MINUTES=15\nSTORAGE_REDIS_FAILOVER_2_CONN_MAX_AGE_IN_MINUTES=30\n\n# Redis Failover Configuration 2 (ID: 4)\nSTORAGE_REDIS_FAILOVER_4_SENTINEL_ADDRESSES=localhost:26379\nSTORAGE_REDIS_FAILOVER_4_DB=0\nSTORAGE_REDIS_FAILOVER_4_DISABLE_IDENTITY=true\nSTORAGE_REDIS_FAILOVER_4_MASTER_NAME=mymaster\nSTORAGE_REDIS_FAILOVER_4_MAX_IDLE_CONN=32\nSTORAGE_REDIS_FAILOVER_4_MIN_IDLE_CONN=20\nSTORAGE_REDIS_FAILOVER_4_MAX_ACTIVE_CONN=32\nSTORAGE_REDIS_FAILOVER_4_MAX_RETRY=-1\nSTORAGE_REDIS_FAILOVER_4_POOL_FIFO=false\nSTORAGE_REDIS_FAILOVER_4_READ_TIMEOUT_IN_MS=3000\nSTORAGE_REDIS_FAILOVER_4_WRITE_TIMEOUT_IN_MS=3000\nSTORAGE_REDIS_FAILOVER_4_POOL_TIMEOUT_IN_MS=3000\nSTORAGE_REDIS_FAILOVER_4_POOL_SIZE=32\nSTORAGE_REDIS_FAILOVER_4_CONN_MAX_IDLE_TIMEOUT_IN_MINUTES=15\nSTORAGE_REDIS_FAILOVER_4_CONN_MAX_AGE_IN_MINUTES=30\n\n# High-Performance Redis Configuration (ID: 6)\nSTORAGE_REDIS_FAILOVER_6_CONN_MAX_AGE_IN_MINUTES=-1\nSTORAGE_REDIS_FAILOVER_6_CONN_MAX_IDLE_TIMEOUT_IN_MINUTES=30\nSTORAGE_REDIS_FAILOVER_6_DB=0\nSTORAGE_REDIS_FAILOVER_6_DISABLE_IDENTITY=true\nSTORAGE_REDIS_FAILOVER_6_MASTER_NAME=mymaster\nSTORAGE_REDIS_FAILOVER_6_MAX_ACTIVE_CONN=202\nSTORAGE_REDIS_FAILOVER_6_MAX_IDLE_CONN=157\nSTORAGE_REDIS_FAILOVER_6_MAX_RETRY=-1\nSTORAGE_REDIS_FAILOVER_6_MIN_IDLE_CONN=52\nSTORAGE_REDIS_FAILOVER_6_PASSWORD=\nSTORAGE_REDIS_FAILOVER_6_POOL_FIFO=false\nSTORAGE_REDIS_FAILOVER_6_POOL_SIZE=202\nSTORAGE_REDIS_FAILOVER_6_POOL_TIMEOUT_IN_MS=2\nSTORAGE_REDIS_FAILOVER_6_READ_TIMEOUT_IN_MS=75\nSTORAGE_REDIS_FAILOVER_6_ROUTE_RANDOM=true\nSTORAGE_REDIS_FAILOVER_6_SENTINEL_ADDRESSES=localhost:26379\nSTORAGE_REDIS_FAILOVER_6_WRITE_TIMEOUT_IN_MS=300\n\n# Active Redis configurations\nSTORAGE_REDIS_FAILOVER_ACTIVE_CONFIG_IDS=2,4,6\n"})}),"\n",(0,s.jsx)(n.h4,{id:"caching-configuration",children:"Caching Configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# In-Memory Cache\nIN_MEM_CACHE_3_ENABLED=true\nIN_MEM_CACHE_3_NAME=onfs\nIN_MEM_CACHE_3_SIZE_IN_BYTES=10000000\nIN_MEM_CACHE_ACTIVE_CONFIG_IDS=3\n\n# Distributed Cache (uses Redis configurations)\n# Redis configurations (IDs: 2,4,6) can be used for distributed caching\nDISTRIBUTED_CACHE_CONF_IDS=2\n"})}),"\n",(0,s.jsx)(n.h4,{id:"service-discovery-and-configuration",children:"Service Discovery and Configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# ETCD Configuration for service discovery\nETCD_SERVER=0.0.0.0:2379\nETCD_WATCHER_ENABLED=true\n"})}),"\n",(0,s.jsx)(n.h3,{id:"horizon-configuration",children:"Horizon Configuration"}),"\n",(0,s.jsx)(n.p,{children:"Horizon manages the metadata and configuration for the Online Feature Store system."}),"\n",(0,s.jsx)(n.h4,{id:"core-application-settings-1",children:"Core Application Settings"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"APP_NAME=horizon\nAPP_ENVIRONMENT=PROD\nAPP_ENV=production\nAPP_PORT=8082\nAPP_LOG_LEVEL=DEBUG\nAPP_METRIC_SAMPLING_RATE=1\nAPP_GC_PERCENTAGE=1\n"})}),"\n",(0,s.jsx)(n.h4,{id:"database-configuration",children:"Database Configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# MySQL Master Configuration\nMYSQL_MASTER_MAX_POOL_SIZE=5\nMYSQL_MASTER_MIN_POOL_SIZE=2\nMYSQL_MASTER_PASSWORD=\nMYSQL_MASTER_HOST=127.0.0.1\nMYSQL_MASTER_PORT=3306\nMYSQL_DB_NAME=ml_config\nMYSQL_MASTER_USERNAME=root\n\n# MySQL Slave Configuration\nMYSQL_SLAVE_MAX_POOL_SIZE=5\nMYSQL_SLAVE_MIN_POOL_SIZE=2\nMYSQL_SLAVE_PASSWORD=\nMYSQL_SLAVE_HOST=127.0.0.1\nMYSQL_SLAVE_USERNAME=root\nMYSQL_SLAVE_PORT=3306\n"})}),"\n",(0,s.jsx)(n.h4,{id:"scylladb-configuration",children:"ScyllaDB Configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# ScyllaDB for Horizon\nSCYLLA_1_CONTACT_POINTS=localhost\nSCYLLA_1_KEYSPACE=onfs\nSCYLLA_1_NUM_CONNS=1\nSCYLLA_1_PORT=9042\nSCYLLA_1_TIMEOUT_IN_MS=300000\nSCYLLA_1_PASSWORD=\nSCYLLA_1_USERNAME=\nSCYLLA_ACTIVE_CONFIG_IDS=1\n"})}),"\n",(0,s.jsx)(n.h4,{id:"service-integration",children:"Service Integration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# ETCD Configuration\nETCD_WATCHER_ENABLED=true\nETCD_SERVER=localhost:2379\n\n# Integration with Online Feature Store\nONLINE_FEATURE_STORE_APP_NAME=online-feature-store\n"})}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"key-constructs",children:"Key Constructs"}),"\n",(0,s.jsx)(n.p,{children:"Understanding these key constructs is essential for effectively using the Online Feature Store:"}),"\n",(0,s.jsx)(n.h3,{id:"store-id",children:"Store ID"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"Store ID"})," is a unique identifier that represents a data storage configuration within the system. It defines:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Storage Backend"}),": Which underlying storage system (ScyllaDB, Redis, etc.) to use"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Configuration Parameters"}),": Connection settings, timeouts, pool sizes"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Access Patterns"}),": How data is read from and written to the store"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Store IDs are referenced throughout the system to:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Route feature requests to the appropriate storage backend"}),"\n",(0,s.jsx)(n.li,{children:"Apply specific caching strategies"}),"\n",(0,s.jsx)(n.li,{children:"Manage data lifecycle and retention policies"}),"\n",(0,s.jsx)(n.li,{children:"Configure stores in TruffleBox UI for feature groups and entities"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Storage Backend Configuration:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"ScyllaDB Store IDs"}),": ",(0,s.jsx)(n.code,{children:"STORAGE_SCYLLA_ACTIVE_CONFIG_IDS=1,5"})," indicates ScyllaDB configurations with IDs 1 and 5 are active"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Redis Store IDs"}),": ",(0,s.jsx)(n.code,{children:"STORAGE_REDIS_FAILOVER_ACTIVE_CONFIG_IDS=2,4,6"})," indicates Redis configurations with IDs 2, 4, and 6 are active"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Dual Usage of Redis:"}),"\nRedis configurations can serve dual purposes:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"As Storage Backend"}),": Redis IDs (2,4,6) can be configured as primary storage in Store configurations"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"As Distributed Cache"}),": Same Redis IDs can be used for caching via ",(0,s.jsx)(n.code,{children:"DISTRIBUTED_CACHE_CONF_IDS=2"})]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"When creating stores in TruffleBox, you can reference these storage configuration IDs to determine which backend (ScyllaDB ID 1/5 or Redis ID 2/4/6) will be used for your feature data."}),"\n",(0,s.jsx)(n.h3,{id:"entity",children:"Entity"}),"\n",(0,s.jsxs)(n.p,{children:["An ",(0,s.jsx)(n.strong,{children:"Entity"})," represents a logical grouping of related features, typically corresponding to a business object (e.g., User, Product, Transaction). Entities provide:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Namespace"}),": Logical separation of feature groups"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Identity"}),": Primary key definition for feature lookup"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Configuration"}),": Cache settings and storage preferences"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"feature-group",children:"Feature Group"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"Feature Group"})," is a collection of related features that share:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Common Entity"}),": All features belong to the same entity"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Storage Configuration"}),": Same underlying storage and caching strategy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Data Lifecycle"}),": Shared TTL and retention policies"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Access Patterns"}),": Similar read/write characteristics"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"feature",children:"Feature"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"Feature"})," is an individual data point that can be retrieved for machine learning models. Each feature has:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Name"}),": Unique identifier within its feature group"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Data Type"}),": The type of data stored (string, integer, float, etc.)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Default Value"}),": Value returned when feature data is not available"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Source Mapping"}),": How the feature maps to underlying storage columns"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"job",children:"Job"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"Job"})," represents a data processing pipeline that:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Ingests Data"}),": Processes raw data from various sources"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Transforms Features"}),": Applies business logic and computations"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Updates Storage"}),": Writes processed features to the feature store"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Scheduling"}),": Defines when and how often the job runs"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"configuration-hierarchy",children:"Configuration Hierarchy"}),"\n",(0,s.jsx)(n.p,{children:"The system uses a hierarchical configuration approach:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"Store \u2192 Entity \u2192 Feature Group \u2192 Feature\n \u2193 \u2193 \u2193 \u2193\nConfig Identity Collection Individual\nLevel Level Level Level\n"})}),"\n",(0,s.jsx)(n.p,{children:"This hierarchy allows for:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Inheritance"}),": Lower levels inherit settings from higher levels"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Override"}),": Specific configurations can be overridden at each level"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Flexibility"}),": Different storage strategies for different use cases"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h1,{id:"trufflebox-ui-guide",children:"TruffleBox UI Guide"}),"\n",(0,s.jsx)(n.p,{children:"TruffleBox is a comprehensive and intuitive UI to help users onboard new features, models and related entities easily. We will build iteratively and add support overtime for entire feature lifecycle management."}),"\n",(0,s.jsx)(n.h2,{id:"table-of-contents-1",children:"Table of Contents"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#user-flow",children:"User Flow"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#getting-started-with-trufflebox",children:"Getting Started with TruffleBox"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#feature-discovery",children:"Feature Discovery"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#feature-registry",children:"Feature Registry"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#admin-approval-flow",children:"Admin Approval Flow"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#request-management",children:"Request Management"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"user-flow",children:"User Flow"}),"\n",(0,s.jsx)(n.h3,{id:"getting-started-with-trufflebox",children:"Getting Started with TruffleBox"}),"\n",(0,s.jsx)(n.h4,{id:"authentication",children:"Authentication"}),"\n",(0,s.jsx)(n.p,{children:"Users can access TruffleBox through registration or login:"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Registration"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"New users should fill in all details and click Register."}),"\n",(0,s.jsx)(n.li,{children:"Once Registered, Please wait for an admin to activate your User"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Registration Screen",src:i(4125).A+"",width:"3438",height:"1690"})}),"\n",(0,s.jsx)(n.h4,{id:"user-management",children:"User Management"}),"\n",(0,s.jsx)(n.p,{children:"Admin users can manage other users through the User Management interface:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"User Management",src:i(6387).A+"",width:"3398",height:"1676"})}),"\n",(0,s.jsx)(n.p,{children:"In the User Management page, admins can:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"View all registered users"}),"\n",(0,s.jsx)(n.li,{children:"Activate/deactivate user accounts"}),"\n",(0,s.jsx)(n.li,{children:"Modify user roles"}),"\n",(0,s.jsx)(n.li,{children:"Manage user permissions"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This is a crucial step in the user onboarding process as new users must be activated by an admin before they can log in to the system."}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Login"}),": Existing users can login with their registered email and password."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Login Screen",src:i(3239).A+"",width:"3438",height:"1690"})}),"\n",(0,s.jsx)(n.h4,{id:"navigation",children:"Navigation"}),"\n",(0,s.jsx)(n.p,{children:"After logging in, you'll be redirected to the feature-discovery page. Access the Control Center by clicking the hamburger icon in the top left corner."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Control Center Navigation",src:i(5352).A+"",width:"3450",height:"1700"})}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"feature-discovery",children:"Feature Discovery"}),"\n",(0,s.jsx)(n.p,{children:"The Feature Discovery page displays approved entities, feature groups, and features."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Feature Discovery Landing Page",src:i(6063).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"You can:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"View details by clicking the info icon"}),"\n",(0,s.jsx)(n.li,{children:"Edit entities, feature groups, and features as needed"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"entity-management",children:"Entity Management"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Entity Details",src:i(8162).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:'View entity details and edit them (limited to In Memory Cache and Distributed Cache details excluding config ID). Submit changes via "Save Changes" to raise an edit request.'}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Edit Entity",src:i(9992).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.h4,{id:"feature-group-management",children:"Feature Group Management"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Feature Group Details",src:i(598).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"Edit feature groups (TTL, In-Memory Cache Enabled, Distributed Cache Enabled, Layout Version) and submit changes to raise an edit request."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Edit Feature Group",src:i(4664).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.h4,{id:"feature-management",children:"Feature Management"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Feature Details",src:i(1983).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"Edit features (Default Value, Source Base Path, Source Data Column, Storage Provider) and submit changes to raise an edit request."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Edit Features",src:i(2564).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.h4,{id:"store-discovery",children:"Store Discovery"}),"\n",(0,s.jsx)(n.p,{children:"Access Store Discovery from the Control Center to view all stores in the database."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Store Discovery",src:i(5350).A+"",width:"3456",height:"1680"})}),"\n",(0,s.jsx)(n.p,{children:"You can search for specific stores but have view-only access."}),"\n",(0,s.jsx)(n.h4,{id:"job-discovery",children:"Job Discovery"}),"\n",(0,s.jsx)(n.p,{children:"Access Job Discovery from the Control Center to view all jobs in the database."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Job Discovery",src:i(4440).A+"",width:"3456",height:"1680"})}),"\n",(0,s.jsx)(n.p,{children:"You can search for specific jobs but have view-only access."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"feature-registry",children:"Feature Registry"}),"\n",(0,s.jsx)(n.p,{children:"In the Control Center, find the 'Feature Registry' accordion to access various registry options for component registration."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Feature Registry Accordion",src:i(5352).A+"",width:"3450",height:"1700"})}),"\n",(0,s.jsx)(n.h4,{id:"request-status-tracking",children:"Request Status Tracking"}),"\n",(0,s.jsx)(n.p,{children:"After raising a request, track its status in the respective registry page. For rejected requests, view the rejection reason by clicking the info icon in the Actions column."}),"\n",(0,s.jsx)(n.h4,{id:"step-by-step-registration-guide",children:"Step-by-Step Registration Guide"}),"\n",(0,s.jsx)(n.p,{children:"For proper feature lifecycle management, register components in this order:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Store"}),"\n",(0,s.jsx)(n.li,{children:"Job"}),"\n",(0,s.jsx)(n.li,{children:"Entity"}),"\n",(0,s.jsx)(n.li,{children:"Feature Group"}),"\n",(0,s.jsx)(n.li,{children:"Features (if not added during Feature Group registration)"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"store-registry",children:"Store Registry"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Register Store",src:i(3849).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"Access Store Registry from the Control Center to view raised requests and register new stores. Fill required data and submit to raise a request."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Store Details",src:i(9352).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Important Considerations:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Always add primary keys for proper data identification"}),"\n",(0,s.jsx)(n.li,{children:"Accurate store configuration is crucial as changes later can be complex"}),"\n",(0,s.jsx)(n.li,{children:"Admin approval creates a database table with your configuration"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"job-registry",children:"Job Registry"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Create Job",src:i(239).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"Access Job Registry from the Control Center to view raised requests and create new jobs. Fill required data and submit your request."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Job Details",src:i(8610).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"Ensure job details are accurate before proceeding to Entity Registry."}),"\n",(0,s.jsx)(n.h4,{id:"entity-registry",children:"Entity Registry"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Create Entity",src:i(9013).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"Access Entity Registry from the Control Center to view raised requests and create new entities. Fill required data and submit your request."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Entity Detail View",src:i(6172).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Important Considerations:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Ensure entity details align with your data model"}),"\n",(0,s.jsx)(n.li,{children:"The entity serves as a logical container for feature groups"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"feature-group-registry",children:"Feature Group Registry"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Create Feature Group",src:i(2805).A+"",width:"3456",height:"1680"})}),"\n",(0,s.jsx)(n.p,{children:"Access Feature Group Registry from the Control Center to view raised requests and create new feature groups. Fill required data and submit your request."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Feature Group Detail View",src:i(1420).A+"",width:"3456",height:"1680"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Important Considerations:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Primary keys must match the store primary keys"}),"\n",(0,s.jsx)(n.li,{children:"TTL settings determine how long feature data is stored"}),"\n",(0,s.jsx)(n.li,{children:"Configure cache settings based on access patterns"}),"\n",(0,s.jsx)(n.li,{children:"Approved feature groups automatically add necessary columns to the database table"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"feature-addition",children:"Feature Addition"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Add Features",src:i(3581).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:"Access Feature Addition from the Control Center to view raised requests and add new features. Fill required data and submit your request."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Feature Detail View",src:i(7540).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Important Considerations:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Ensure feature data types are compatible with source data"}),"\n",(0,s.jsx)(n.li,{children:"Set appropriate default values and correct source data column mapping"}),"\n",(0,s.jsx)(n.li,{children:"Approved features automatically add columns to the database table"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"need-help",children:"Need Help?"}),"\n",(0,s.jsx)(n.p,{children:"Please reach out to the BharatMLStack core team for any questions about using TruffleBox."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"admin-approval-flow",children:"Admin Approval Flow"}),"\n",(0,s.jsx)(n.p,{children:"As an admin, you're responsible for reviewing and managing user requests."}),"\n",(0,s.jsx)(n.h3,{id:"request-management",children:"Request Management"}),"\n",(0,s.jsx)(n.h4,{id:"viewing-all-requests",children:"Viewing All Requests"}),"\n",(0,s.jsx)(n.p,{children:"After logging in as an admin, you can see all pending requests across different components (Stores, Jobs, Entities, Feature Groups, Features)."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Admin Dashboard",src:i(3247).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsx)(n.h4,{id:"request-approval-process",children:"Request Approval Process"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Review Details"}),": Click the info icon to view complete request details"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Request Details",src:i(3247).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Approval Option"}),": After review, use the approve/reject buttons"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Approval Buttons",src:i(3247).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Approval Process"}),":",(0,s.jsx)(n.br,{}),"\n",'Click "Approve" to process the request. The system will create database tables or add columns as needed. A success message confirms completion.']}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Approval Success",src:i(3247).A+"",width:"3450",height:"1690"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Rejection Process"}),":",(0,s.jsx)(n.br,{}),"\n",'Click "Reject" to deny a request. Provide a rejection reason to help users understand why their request wasn\'t approved.']}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Rejection Reason",src:i(2538).A+"",width:"3456",height:"1680"})}),"\n",(0,s.jsx)(n.p,{children:"Users can view the rejection reason in their respective registry page."}),"\n",(0,s.jsx)(n.h4,{id:"admin-support",children:"Admin Support"}),"\n",(0,s.jsx)(n.p,{children:"If you need assistance with admin functions, please contact the BharatMLStack core team."}),"\n",(0,s.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,s.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,s.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\ud83d\udcac ",(0,s.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,s.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,s.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,s.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,s.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,s.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,s.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,s.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)("div",{align:"center",children:(0,s.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,s.jsx)("div",{align:"center",children:(0,s.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1420:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-fg-details-1b1100bbb5d23fac31414b15f2a59366.png"},1983:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-feature-discovery-feature-details-b780eb1ede246eb257862a46f0fdb53e.png"},2538:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-reject-popup-9941183f1128e19034f41970d218d72f.png"},2564:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-edit-features-41cb78c09d70203c166fce91976d2ba0.png"},2805:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-fg-9c3b22e62b389f2c1baf968a6e201964.png"},3239:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-login-de1cbf15b2daa5c532875a94a4ad1a47.png"},3247:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-approve-store-1057c0853f92becfa9b1f87d165a72f9.png"},3581:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-add-features-6cb39960d91af3ee1c896492188cfcb5.png"},3849:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-store-d6f80ceb9a6570b225bba4653ac22dd8.png"},4125:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-registration-aed7738afc652b6418bdc00966850ec0.png"},4440:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-job-discovery-3fac78c4b09b6c76a7bc1dd0738cc93d.png"},4664:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-edit-fg-edc1a8999700e5c1e9ff023fe9f6413f.png"},5350:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-store-discovery-8c9042352255fff36b35b4aa193583f7.png"},5352:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-navigation-0e472fd13ccdae9448011eb9aebb990e.png"},6063:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-feature-discovery-c3a8456bb04479842666120a0ec082e6.png"},6172:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-entity-details-016ab5c5b2fef9f58bde75e6a07c9823.png"},6387:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-user-management-2c50fa8488f21ff07b9925c48a10f7cd.png"},7540:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-add-features-details-278a519cdfe25bead880d7a18e0b858e.png"},8162:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-feature-discovery-entity-details-839bb44b2cd99129eeb0ee785d19152c.png"},8453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>o});var r=i(6540);const s={},t=r.createContext(s);function a(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(t.Provider,{value:n},e.children)}},8610:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-job-details-075436efba1df107ac7e42164ff6494a.png"},9013:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-entity-fe6449f47304e0377107d8e5b3ce1d30.png"},9352:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-register-store-details-a36537beae9ac91576186b193e858112.png"},9992:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/v1.0.0-trufflebox-edit-entity-0c3bb1263b53ed678ae2f9310441f3d7.png"}}]); \ No newline at end of file diff --git a/docs/assets/js/17896441.4ff7d852.js b/docs/assets/js/17896441.4ff7d852.js new file mode 100644 index 00000000..915c5a76 --- /dev/null +++ b/docs/assets/js/17896441.4ff7d852.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8401],{594:(e,n,t)=>{t.d(n,{A:()=>j});t(6540);var s=t(4164),a=t(7559),i=t(6972),l=t(9169),o=t(8774),r=t(1312),c=t(6025),d=t(4848);function u(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,d.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const m={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function h(){const e=(0,c.Ay)("/");return(0,d.jsx)("li",{className:"breadcrumbs__item",children:(0,d.jsx)(o.A,{"aria-label":(0,r.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,d.jsx)(u,{className:m.breadcrumbHomeIcon})})})}var b=t(5260),v=t(4586);function x(e){const n=function({breadcrumbs:e}){const{siteConfig:n}=(0,v.A)();return{"@context":"https://schema.org","@type":"BreadcrumbList",itemListElement:e.filter(e=>e.href).map((e,t)=>({"@type":"ListItem",position:t+1,name:e.label,item:`${n.url}${e.href}`}))}}({breadcrumbs:e.breadcrumbs});return(0,d.jsx)(b.A,{children:(0,d.jsx)("script",{type:"application/ld+json",children:JSON.stringify(n)})})}const g={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function f({children:e,href:n,isLast:t}){const s="breadcrumbs__link";return t?(0,d.jsx)("span",{className:s,children:e}):n?(0,d.jsx)(o.A,{className:s,href:n,children:(0,d.jsx)("span",{children:e})}):(0,d.jsx)("span",{className:s,children:e})}function p({children:e,active:n}){return(0,d.jsx)("li",{className:(0,s.A)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:e})}function j(){const e=(0,i.OF)(),n=(0,l.Dt)();return e?(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(x,{breadcrumbs:e}),(0,d.jsx)("nav",{className:(0,s.A)(a.G.docs.docBreadcrumbs,g.breadcrumbsContainer),"aria-label":(0,r.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,d.jsxs)("ul",{className:"breadcrumbs",children:[n&&(0,d.jsx)(h,{}),e.map((n,t)=>{const s=t===e.length-1,a="category"===n.type&&n.linkUnlisted?void 0:n.href;return(0,d.jsx)(p,{active:s,children:(0,d.jsx)(f,{href:a,isLast:s,children:n.label})},t)})]})})]}):null}},833:(e,n,t)=>{t.r(n),t.d(n,{default:()=>F});var s=t(6540),a=t(5500),i=t(9532),l=t(4848);const o=s.createContext(null);function r({children:e,content:n}){const t=function(e){return(0,s.useMemo)(()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc}),[e])}(n);return(0,l.jsx)(o.Provider,{value:t,children:e})}function c(){const e=(0,s.useContext)(o);if(null===e)throw new i.dV("DocProvider");return e}function d(){const{metadata:e,frontMatter:n,assets:t}=c();return(0,l.jsx)(a.be,{title:e.title,description:e.description,keywords:n.keywords,image:t.image??n.image})}var u=t(4164),m=t(4581),h=t(7719);function b(){const{metadata:e}=c();return(0,l.jsx)(h.A,{className:"docusaurus-mt-lg",previous:e.previous,next:e.next})}var v=t(1878),x=t(4267),g=t(7559),f=t(2053),p=t(4336);function j(){const{metadata:e}=c(),{editUrl:n,lastUpdatedAt:t,lastUpdatedBy:s,tags:a}=e,i=a.length>0,o=!!(n||t||s);return i||o?(0,l.jsxs)("footer",{className:(0,u.A)(g.G.docs.docFooter,"docusaurus-mt-lg"),children:[i&&(0,l.jsx)("div",{className:(0,u.A)("row margin-top--sm",g.G.docs.docFooterTagsRow),children:(0,l.jsx)("div",{className:"col",children:(0,l.jsx)(f.A,{tags:a})})}),o&&(0,l.jsx)(p.A,{className:(0,u.A)("margin-top--sm",g.G.docs.docFooterEditMetaRow),editUrl:n,lastUpdatedAt:t,lastUpdatedBy:s})]}):null}var A=t(1422),N=t(5195),C=t(1312);const L={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function _({collapsed:e,...n}){return(0,l.jsx)("button",{type:"button",...n,className:(0,u.A)("clean-btn",L.tocCollapsibleButton,!e&&L.tocCollapsibleButtonExpanded,n.className),children:(0,l.jsx)(C.A,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const T={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function k({toc:e,className:n,minHeadingLevel:t,maxHeadingLevel:s}){const{collapsed:a,toggleCollapsed:i}=(0,A.u)({initialState:!0});return(0,l.jsxs)("div",{className:(0,u.A)(T.tocCollapsible,!a&&T.tocCollapsibleExpanded,n),children:[(0,l.jsx)(_,{collapsed:a,onClick:i}),(0,l.jsx)(A.N,{lazy:!0,className:T.tocCollapsibleContent,collapsed:a,children:(0,l.jsx)(N.A,{toc:e,minHeadingLevel:t,maxHeadingLevel:s})})]})}const H={tocMobile:"tocMobile_ITEo"};function y(){const{toc:e,frontMatter:n}=c();return(0,l.jsx)(k,{toc:e,minHeadingLevel:n.toc_min_heading_level,maxHeadingLevel:n.toc_max_heading_level,className:(0,u.A)(g.G.docs.docTocMobile,H.tocMobile)})}var M=t(7763);function B(){const{toc:e,frontMatter:n}=c();return(0,l.jsx)(M.A,{toc:e,minHeadingLevel:n.toc_min_heading_level,maxHeadingLevel:n.toc_max_heading_level,className:g.G.docs.docTocDesktop})}var I=t(1107),w=t(3253);function E({children:e}){const n=function(){const{metadata:e,frontMatter:n,contentTitle:t}=c();return n.hide_title||void 0!==t?null:e.title}();return(0,l.jsxs)("div",{className:(0,u.A)(g.G.docs.docMarkdown,"markdown"),children:[n&&(0,l.jsx)("header",{children:(0,l.jsx)(I.A,{as:"h1",children:n})}),(0,l.jsx)(w.A,{children:e})]})}var V=t(594),O=t(1689);const R={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function G({children:e}){const n=function(){const{frontMatter:e,toc:n}=c(),t=(0,m.l)(),s=e.hide_table_of_contents,a=!s&&n.length>0;return{hidden:s,mobile:a?(0,l.jsx)(y,{}):void 0,desktop:!a||"desktop"!==t&&"ssr"!==t?void 0:(0,l.jsx)(B,{})}}(),{metadata:t}=c();return(0,l.jsxs)("div",{className:"row",children:[(0,l.jsxs)("div",{className:(0,u.A)("col",!n.hidden&&R.docItemCol),children:[(0,l.jsx)(O.A,{metadata:t}),(0,l.jsx)(v.A,{}),(0,l.jsxs)("div",{className:R.docItemContainer,children:[(0,l.jsxs)("article",{children:[(0,l.jsx)(V.A,{}),(0,l.jsx)(x.A,{}),n.mobile,(0,l.jsx)(E,{children:e}),(0,l.jsx)(j,{})]}),(0,l.jsx)(b,{})]})]}),n.desktop&&(0,l.jsx)("div",{className:"col col--3",children:n.desktop})]})}function F(e){const n=`docs-doc-id-${e.content.metadata.id}`,t=e.content;return(0,l.jsx)(r,{content:e.content,children:(0,l.jsxs)(a.e3,{className:n,children:[(0,l.jsx)(d,{}),(0,l.jsx)(G,{children:(0,l.jsx)(t,{})})]})})}},1689:(e,n,t)=>{t.d(n,{A:()=>d});t(6540);var s=t(4164),a=t(4084),i=t(7559),l=t(7293),o=t(4848);function r({className:e}){return(0,o.jsx)(l.A,{type:"caution",title:(0,o.jsx)(a.Yh,{}),className:(0,s.A)(e,i.G.common.draftBanner),children:(0,o.jsx)(a.TT,{})})}var c=t(2234);function d({metadata:e}){const{unlisted:n,frontMatter:t}=e;return(0,o.jsxs)(o.Fragment,{children:[(n||t.unlisted)&&(0,o.jsx)(c.A,{}),t.draft&&(0,o.jsx)(r,{})]})}},1878:(e,n,t)=>{t.d(n,{A:()=>x});t(6540);var s=t(4164),a=t(4586),i=t(8774),l=t(1312),o=t(4070),r=t(7559),c=t(3886),d=t(3025),u=t(4848);const m={unreleased:function({siteTitle:e,versionMetadata:n}){return(0,u.jsx)(l.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:e,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function({siteTitle:e,versionMetadata:n}){return(0,u.jsx)(l.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:e,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function h(e){const n=m[e.versionMetadata.banner];return(0,u.jsx)(n,{...e})}function b({versionLabel:e,to:n,onClick:t}){return(0,u.jsx)(l.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:e,latestVersionLink:(0,u.jsx)("b",{children:(0,u.jsx)(i.A,{to:n,onClick:t,children:(0,u.jsx)(l.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function v({className:e,versionMetadata:n}){const{siteConfig:{title:t}}=(0,a.A)(),{pluginId:i}=(0,o.vT)({failfast:!0}),{savePreferredVersionName:l}=(0,c.g1)(i),{latestDocSuggestion:d,latestVersionSuggestion:m}=(0,o.HW)(i),v=d??(x=m).docs.find(e=>e.id===x.mainDocId);var x;return(0,u.jsxs)("div",{className:(0,s.A)(e,r.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,u.jsx)("div",{children:(0,u.jsx)(h,{siteTitle:t,versionMetadata:n})}),(0,u.jsx)("div",{className:"margin-top--md",children:(0,u.jsx)(b,{versionLabel:m.label,to:v.path,onClick:()=>l(m.name)})})]})}function x({className:e}){const n=(0,d.r)();return n.banner?(0,u.jsx)(v,{className:e,versionMetadata:n}):null}},2053:(e,n,t)=>{t.d(n,{A:()=>r});t(6540);var s=t(4164),a=t(1312),i=t(6133);const l={tags:"tags_jXut",tag:"tag_QGVx"};var o=t(4848);function r({tags:e}){return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("b",{children:(0,o.jsx)(a.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,o.jsx)("ul",{className:(0,s.A)(l.tags,"padding--none","margin-left--sm"),children:e.map(e=>(0,o.jsx)("li",{className:l.tag,children:(0,o.jsx)(i.A,{...e})},e.permalink))})]})}},2234:(e,n,t)=>{t.d(n,{A:()=>c});t(6540);var s=t(4164),a=t(7559),i=t(4084),l=t(7293),o=t(4848);function r({className:e}){return(0,o.jsx)(l.A,{type:"caution",title:(0,o.jsx)(i.Rc,{}),className:(0,s.A)(e,a.G.common.unlistedBanner),children:(0,o.jsx)(i.Uh,{})})}function c(e){return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(i.AE,{}),(0,o.jsx)(r,{...e})]})}},4084:(e,n,t)=>{t.d(n,{AE:()=>r,Rc:()=>l,TT:()=>d,Uh:()=>o,Yh:()=>c});t(6540);var s=t(1312),a=t(5260),i=t(4848);function l(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function o(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function r(){return(0,i.jsx)(a.A,{children:(0,i.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}},4267:(e,n,t)=>{t.d(n,{A:()=>r});t(6540);var s=t(4164),a=t(1312),i=t(7559),l=t(3025),o=t(4848);function r({className:e}){const n=(0,l.r)();return n.badge?(0,o.jsx)("span",{className:(0,s.A)(e,i.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,o.jsx)(a.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label},children:"Version: {versionLabel}"})}):null}},5195:(e,n,t)=>{t.d(n,{A:()=>v});var s=t(6540),a=t(6342);function i(e){const n=e.map(e=>({...e,parentIndex:-1,children:[]})),t=Array(7).fill(-1);n.forEach((e,n)=>{const s=t.slice(2,e.level);e.parentIndex=Math.max(...s),t[e.level]=n});const s=[];return n.forEach(e=>{const{parentIndex:t,...a}=e;t>=0?n[t].children.push(a):s.push(a)}),s}function l({toc:e,minHeadingLevel:n,maxHeadingLevel:t}){return e.flatMap(e=>{const s=l({toc:e.children,minHeadingLevel:n,maxHeadingLevel:t});return function(e){return e.level>=n&&e.level<=t}(e)?[{...e,children:s}]:s})}function o(e){const n=e.getBoundingClientRect();return n.top===n.bottom?o(e.parentNode):n}function r(e,{anchorTopOffset:n}){const t=e.find(e=>o(e).top>=n);if(t){return function(e){return e.top>0&&e.bottom{e.current=n?0:document.querySelector(".navbar").clientHeight},[n]),e}function d(e){const n=(0,s.useRef)(void 0),t=c();(0,s.useEffect)(()=>{if(!e)return()=>{};const{linkClassName:s,linkActiveClassName:a,minHeadingLevel:i,maxHeadingLevel:l}=e;function o(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(s),o=function({minHeadingLevel:e,maxHeadingLevel:n}){const t=[];for(let s=e;s<=n;s+=1)t.push(`h${s}.anchor`);return Array.from(document.querySelectorAll(t.join()))}({minHeadingLevel:i,maxHeadingLevel:l}),c=r(o,{anchorTopOffset:t.current}),d=e.find(e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e));e.forEach(e=>{!function(e,t){t?(n.current&&n.current!==e&&n.current.classList.remove(a),e.classList.add(a),n.current=e):e.classList.remove(a)}(e,e===d)})}return document.addEventListener("scroll",o),document.addEventListener("resize",o),o(),()=>{document.removeEventListener("scroll",o),document.removeEventListener("resize",o)}},[e,t])}var u=t(8774),m=t(4848);function h({toc:e,className:n,linkClassName:t,isChild:s}){return e.length?(0,m.jsx)("ul",{className:s?void 0:n,children:e.map(e=>(0,m.jsxs)("li",{children:[(0,m.jsx)(u.A,{to:`#${e.id}`,className:t??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,m.jsx)(h,{isChild:!0,toc:e.children,className:n,linkClassName:t})]},e.id))}):null}const b=s.memo(h);function v({toc:e,className:n="table-of-contents table-of-contents__left-border",linkClassName:t="table-of-contents__link",linkActiveClassName:o,minHeadingLevel:r,maxHeadingLevel:c,...u}){const h=(0,a.p)(),v=r??h.tableOfContents.minHeadingLevel,x=c??h.tableOfContents.maxHeadingLevel,g=function({toc:e,minHeadingLevel:n,maxHeadingLevel:t}){return(0,s.useMemo)(()=>l({toc:i(e),minHeadingLevel:n,maxHeadingLevel:t}),[e,n,t])}({toc:e,minHeadingLevel:v,maxHeadingLevel:x});return d((0,s.useMemo)(()=>{if(t&&o)return{linkClassName:t,linkActiveClassName:o,minHeadingLevel:v,maxHeadingLevel:x}},[t,o,v,x])),(0,m.jsx)(b,{toc:g,className:n,linkClassName:t,...u})}},6133:(e,n,t)=>{t.d(n,{A:()=>o});t(6540);var s=t(4164),a=t(8774);const i={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var l=t(4848);function o({permalink:e,label:n,count:t,description:o}){return(0,l.jsxs)(a.A,{rel:"tag",href:e,title:o,className:(0,s.A)(i.tag,t?i.tagWithCount:i.tagRegular),children:[n,t&&(0,l.jsx)("span",{children:t})]})}},7719:(e,n,t)=>{t.d(n,{A:()=>o});t(6540);var s=t(4164),a=t(1312),i=t(9022),l=t(4848);function o(e){const{className:n,previous:t,next:o}=e;return(0,l.jsxs)("nav",{className:(0,s.A)(n,"pagination-nav"),"aria-label":(0,a.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,l.jsx)(i.A,{...t,subLabel:(0,l.jsx)(a.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),o&&(0,l.jsx)(i.A,{...o,subLabel:(0,l.jsx)(a.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},7763:(e,n,t)=>{t.d(n,{A:()=>c});t(6540);var s=t(4164),a=t(5195);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var l=t(4848);const o="table-of-contents__link toc-highlight",r="table-of-contents__link--active";function c({className:e,...n}){return(0,l.jsx)("div",{className:(0,s.A)(i.tableOfContents,"thin-scrollbar",e),children:(0,l.jsx)(a.A,{...n,linkClassName:o,linkActiveClassName:r})})}},9022:(e,n,t)=>{t.d(n,{A:()=>l});t(6540);var s=t(4164),a=t(8774),i=t(4848);function l(e){const{permalink:n,title:t,subLabel:l,isNext:o}=e;return(0,i.jsxs)(a.A,{className:(0,s.A)("pagination-nav__link",o?"pagination-nav__link--next":"pagination-nav__link--prev"),to:n,children:[l&&(0,i.jsx)("div",{className:"pagination-nav__sublabel",children:l}),(0,i.jsx)("div",{className:"pagination-nav__label",children:t})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/17896441.e023d99a.js b/docs/assets/js/17896441.e023d99a.js deleted file mode 100644 index 5e076aa5..00000000 --- a/docs/assets/js/17896441.e023d99a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8401],{594:(e,n,t)=>{t.d(n,{A:()=>j});t(6540);var s=t(4164),a=t(7559),i=t(6972),l=t(9169),o=t(8774),r=t(1312),c=t(6025),d=t(4848);function u(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,d.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const m={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function h(){const e=(0,c.Ay)("/");return(0,d.jsx)("li",{className:"breadcrumbs__item",children:(0,d.jsx)(o.A,{"aria-label":(0,r.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,d.jsx)(u,{className:m.breadcrumbHomeIcon})})})}var b=t(5260),v=t(4586);function x(e){const n=function({breadcrumbs:e}){const{siteConfig:n}=(0,v.A)();return{"@context":"https://schema.org","@type":"BreadcrumbList",itemListElement:e.filter((e=>e.href)).map(((e,t)=>({"@type":"ListItem",position:t+1,name:e.label,item:`${n.url}${e.href}`})))}}({breadcrumbs:e.breadcrumbs});return(0,d.jsx)(b.A,{children:(0,d.jsx)("script",{type:"application/ld+json",children:JSON.stringify(n)})})}const g={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function f({children:e,href:n,isLast:t}){const s="breadcrumbs__link";return t?(0,d.jsx)("span",{className:s,children:e}):n?(0,d.jsx)(o.A,{className:s,href:n,children:(0,d.jsx)("span",{children:e})}):(0,d.jsx)("span",{className:s,children:e})}function p({children:e,active:n}){return(0,d.jsx)("li",{className:(0,s.A)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:e})}function j(){const e=(0,i.OF)(),n=(0,l.Dt)();return e?(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(x,{breadcrumbs:e}),(0,d.jsx)("nav",{className:(0,s.A)(a.G.docs.docBreadcrumbs,g.breadcrumbsContainer),"aria-label":(0,r.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,d.jsxs)("ul",{className:"breadcrumbs",children:[n&&(0,d.jsx)(h,{}),e.map(((n,t)=>{const s=t===e.length-1,a="category"===n.type&&n.linkUnlisted?void 0:n.href;return(0,d.jsx)(p,{active:s,children:(0,d.jsx)(f,{href:a,isLast:s,children:n.label})},t)}))]})})]}):null}},833:(e,n,t)=>{t.r(n),t.d(n,{default:()=>F});var s=t(6540),a=t(5500),i=t(9532),l=t(4848);const o=s.createContext(null);function r({children:e,content:n}){const t=function(e){return(0,s.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return(0,l.jsx)(o.Provider,{value:t,children:e})}function c(){const e=(0,s.useContext)(o);if(null===e)throw new i.dV("DocProvider");return e}function d(){const{metadata:e,frontMatter:n,assets:t}=c();return(0,l.jsx)(a.be,{title:e.title,description:e.description,keywords:n.keywords,image:t.image??n.image})}var u=t(4164),m=t(4581),h=t(7719);function b(){const{metadata:e}=c();return(0,l.jsx)(h.A,{className:"docusaurus-mt-lg",previous:e.previous,next:e.next})}var v=t(1878),x=t(4267),g=t(7559),f=t(2053),p=t(4336);function j(){const{metadata:e}=c(),{editUrl:n,lastUpdatedAt:t,lastUpdatedBy:s,tags:a}=e,i=a.length>0,o=!!(n||t||s);return i||o?(0,l.jsxs)("footer",{className:(0,u.A)(g.G.docs.docFooter,"docusaurus-mt-lg"),children:[i&&(0,l.jsx)("div",{className:(0,u.A)("row margin-top--sm",g.G.docs.docFooterTagsRow),children:(0,l.jsx)("div",{className:"col",children:(0,l.jsx)(f.A,{tags:a})})}),o&&(0,l.jsx)(p.A,{className:(0,u.A)("margin-top--sm",g.G.docs.docFooterEditMetaRow),editUrl:n,lastUpdatedAt:t,lastUpdatedBy:s})]}):null}var A=t(1422),N=t(5195),C=t(1312);const L={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function _({collapsed:e,...n}){return(0,l.jsx)("button",{type:"button",...n,className:(0,u.A)("clean-btn",L.tocCollapsibleButton,!e&&L.tocCollapsibleButtonExpanded,n.className),children:(0,l.jsx)(C.A,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const T={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function k({toc:e,className:n,minHeadingLevel:t,maxHeadingLevel:s}){const{collapsed:a,toggleCollapsed:i}=(0,A.u)({initialState:!0});return(0,l.jsxs)("div",{className:(0,u.A)(T.tocCollapsible,!a&&T.tocCollapsibleExpanded,n),children:[(0,l.jsx)(_,{collapsed:a,onClick:i}),(0,l.jsx)(A.N,{lazy:!0,className:T.tocCollapsibleContent,collapsed:a,children:(0,l.jsx)(N.A,{toc:e,minHeadingLevel:t,maxHeadingLevel:s})})]})}const H={tocMobile:"tocMobile_ITEo"};function y(){const{toc:e,frontMatter:n}=c();return(0,l.jsx)(k,{toc:e,minHeadingLevel:n.toc_min_heading_level,maxHeadingLevel:n.toc_max_heading_level,className:(0,u.A)(g.G.docs.docTocMobile,H.tocMobile)})}var M=t(7763);function B(){const{toc:e,frontMatter:n}=c();return(0,l.jsx)(M.A,{toc:e,minHeadingLevel:n.toc_min_heading_level,maxHeadingLevel:n.toc_max_heading_level,className:g.G.docs.docTocDesktop})}var I=t(1107),w=t(3253);function E({children:e}){const n=function(){const{metadata:e,frontMatter:n,contentTitle:t}=c();return n.hide_title||void 0!==t?null:e.title}();return(0,l.jsxs)("div",{className:(0,u.A)(g.G.docs.docMarkdown,"markdown"),children:[n&&(0,l.jsx)("header",{children:(0,l.jsx)(I.A,{as:"h1",children:n})}),(0,l.jsx)(w.A,{children:e})]})}var V=t(594),O=t(1689);const R={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function G({children:e}){const n=function(){const{frontMatter:e,toc:n}=c(),t=(0,m.l)(),s=e.hide_table_of_contents,a=!s&&n.length>0;return{hidden:s,mobile:a?(0,l.jsx)(y,{}):void 0,desktop:!a||"desktop"!==t&&"ssr"!==t?void 0:(0,l.jsx)(B,{})}}(),{metadata:t}=c();return(0,l.jsxs)("div",{className:"row",children:[(0,l.jsxs)("div",{className:(0,u.A)("col",!n.hidden&&R.docItemCol),children:[(0,l.jsx)(O.A,{metadata:t}),(0,l.jsx)(v.A,{}),(0,l.jsxs)("div",{className:R.docItemContainer,children:[(0,l.jsxs)("article",{children:[(0,l.jsx)(V.A,{}),(0,l.jsx)(x.A,{}),n.mobile,(0,l.jsx)(E,{children:e}),(0,l.jsx)(j,{})]}),(0,l.jsx)(b,{})]})]}),n.desktop&&(0,l.jsx)("div",{className:"col col--3",children:n.desktop})]})}function F(e){const n=`docs-doc-id-${e.content.metadata.id}`,t=e.content;return(0,l.jsx)(r,{content:e.content,children:(0,l.jsxs)(a.e3,{className:n,children:[(0,l.jsx)(d,{}),(0,l.jsx)(G,{children:(0,l.jsx)(t,{})})]})})}},1689:(e,n,t)=>{t.d(n,{A:()=>d});t(6540);var s=t(4164),a=t(4084),i=t(7559),l=t(7293),o=t(4848);function r({className:e}){return(0,o.jsx)(l.A,{type:"caution",title:(0,o.jsx)(a.Yh,{}),className:(0,s.A)(e,i.G.common.draftBanner),children:(0,o.jsx)(a.TT,{})})}var c=t(2234);function d({metadata:e}){const{unlisted:n,frontMatter:t}=e;return(0,o.jsxs)(o.Fragment,{children:[(n||t.unlisted)&&(0,o.jsx)(c.A,{}),t.draft&&(0,o.jsx)(r,{})]})}},1878:(e,n,t)=>{t.d(n,{A:()=>x});t(6540);var s=t(4164),a=t(4586),i=t(8774),l=t(1312),o=t(4070),r=t(7559),c=t(3886),d=t(3025),u=t(4848);const m={unreleased:function({siteTitle:e,versionMetadata:n}){return(0,u.jsx)(l.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:e,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function({siteTitle:e,versionMetadata:n}){return(0,u.jsx)(l.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:e,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function h(e){const n=m[e.versionMetadata.banner];return(0,u.jsx)(n,{...e})}function b({versionLabel:e,to:n,onClick:t}){return(0,u.jsx)(l.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:e,latestVersionLink:(0,u.jsx)("b",{children:(0,u.jsx)(i.A,{to:n,onClick:t,children:(0,u.jsx)(l.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function v({className:e,versionMetadata:n}){const{siteConfig:{title:t}}=(0,a.A)(),{pluginId:i}=(0,o.vT)({failfast:!0}),{savePreferredVersionName:l}=(0,c.g1)(i),{latestDocSuggestion:d,latestVersionSuggestion:m}=(0,o.HW)(i),v=d??(x=m).docs.find((e=>e.id===x.mainDocId));var x;return(0,u.jsxs)("div",{className:(0,s.A)(e,r.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,u.jsx)("div",{children:(0,u.jsx)(h,{siteTitle:t,versionMetadata:n})}),(0,u.jsx)("div",{className:"margin-top--md",children:(0,u.jsx)(b,{versionLabel:m.label,to:v.path,onClick:()=>l(m.name)})})]})}function x({className:e}){const n=(0,d.r)();return n.banner?(0,u.jsx)(v,{className:e,versionMetadata:n}):null}},2053:(e,n,t)=>{t.d(n,{A:()=>r});t(6540);var s=t(4164),a=t(1312),i=t(6133);const l={tags:"tags_jXut",tag:"tag_QGVx"};var o=t(4848);function r({tags:e}){return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("b",{children:(0,o.jsx)(a.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,o.jsx)("ul",{className:(0,s.A)(l.tags,"padding--none","margin-left--sm"),children:e.map((e=>(0,o.jsx)("li",{className:l.tag,children:(0,o.jsx)(i.A,{...e})},e.permalink)))})]})}},2234:(e,n,t)=>{t.d(n,{A:()=>c});t(6540);var s=t(4164),a=t(4084),i=t(7559),l=t(7293),o=t(4848);function r({className:e}){return(0,o.jsx)(l.A,{type:"caution",title:(0,o.jsx)(a.Rc,{}),className:(0,s.A)(e,i.G.common.unlistedBanner),children:(0,o.jsx)(a.Uh,{})})}function c(e){return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(a.AE,{}),(0,o.jsx)(r,{...e})]})}},4084:(e,n,t)=>{t.d(n,{AE:()=>r,Rc:()=>l,TT:()=>d,Uh:()=>o,Yh:()=>c});t(6540);var s=t(1312),a=t(5260),i=t(4848);function l(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function o(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function r(){return(0,i.jsx)(a.A,{children:(0,i.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}},4267:(e,n,t)=>{t.d(n,{A:()=>r});t(6540);var s=t(4164),a=t(1312),i=t(7559),l=t(3025),o=t(4848);function r({className:e}){const n=(0,l.r)();return n.badge?(0,o.jsx)("span",{className:(0,s.A)(e,i.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,o.jsx)(a.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label},children:"Version: {versionLabel}"})}):null}},5195:(e,n,t)=>{t.d(n,{A:()=>v});var s=t(6540),a=t(6342);function i(e){const n=e.map((e=>({...e,parentIndex:-1,children:[]}))),t=Array(7).fill(-1);n.forEach(((e,n)=>{const s=t.slice(2,e.level);e.parentIndex=Math.max(...s),t[e.level]=n}));const s=[];return n.forEach((e=>{const{parentIndex:t,...a}=e;t>=0?n[t].children.push(a):s.push(a)})),s}function l({toc:e,minHeadingLevel:n,maxHeadingLevel:t}){return e.flatMap((e=>{const s=l({toc:e.children,minHeadingLevel:n,maxHeadingLevel:t});return function(e){return e.level>=n&&e.level<=t}(e)?[{...e,children:s}]:s}))}function o(e){const n=e.getBoundingClientRect();return n.top===n.bottom?o(e.parentNode):n}function r(e,{anchorTopOffset:n}){const t=e.find((e=>o(e).top>=n));if(t){return function(e){return e.top>0&&e.bottom{e.current=n?0:document.querySelector(".navbar").clientHeight}),[n]),e}function d(e){const n=(0,s.useRef)(void 0),t=c();(0,s.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:s,linkActiveClassName:a,minHeadingLevel:i,maxHeadingLevel:l}=e;function o(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(s),o=function({minHeadingLevel:e,maxHeadingLevel:n}){const t=[];for(let s=e;s<=n;s+=1)t.push(`h${s}.anchor`);return Array.from(document.querySelectorAll(t.join()))}({minHeadingLevel:i,maxHeadingLevel:l}),c=r(o,{anchorTopOffset:t.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,t){t?(n.current&&n.current!==e&&n.current.classList.remove(a),e.classList.add(a),n.current=e):e.classList.remove(a)}(e,e===d)}))}return document.addEventListener("scroll",o),document.addEventListener("resize",o),o(),()=>{document.removeEventListener("scroll",o),document.removeEventListener("resize",o)}}),[e,t])}var u=t(8774),m=t(4848);function h({toc:e,className:n,linkClassName:t,isChild:s}){return e.length?(0,m.jsx)("ul",{className:s?void 0:n,children:e.map((e=>(0,m.jsxs)("li",{children:[(0,m.jsx)(u.A,{to:`#${e.id}`,className:t??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,m.jsx)(h,{isChild:!0,toc:e.children,className:n,linkClassName:t})]},e.id)))}):null}const b=s.memo(h);function v({toc:e,className:n="table-of-contents table-of-contents__left-border",linkClassName:t="table-of-contents__link",linkActiveClassName:o,minHeadingLevel:r,maxHeadingLevel:c,...u}){const h=(0,a.p)(),v=r??h.tableOfContents.minHeadingLevel,x=c??h.tableOfContents.maxHeadingLevel,g=function({toc:e,minHeadingLevel:n,maxHeadingLevel:t}){return(0,s.useMemo)((()=>l({toc:i(e),minHeadingLevel:n,maxHeadingLevel:t})),[e,n,t])}({toc:e,minHeadingLevel:v,maxHeadingLevel:x});return d((0,s.useMemo)((()=>{if(t&&o)return{linkClassName:t,linkActiveClassName:o,minHeadingLevel:v,maxHeadingLevel:x}}),[t,o,v,x])),(0,m.jsx)(b,{toc:g,className:n,linkClassName:t,...u})}},6133:(e,n,t)=>{t.d(n,{A:()=>o});t(6540);var s=t(4164),a=t(8774);const i={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var l=t(4848);function o({permalink:e,label:n,count:t,description:o}){return(0,l.jsxs)(a.A,{rel:"tag",href:e,title:o,className:(0,s.A)(i.tag,t?i.tagWithCount:i.tagRegular),children:[n,t&&(0,l.jsx)("span",{children:t})]})}},7719:(e,n,t)=>{t.d(n,{A:()=>o});t(6540);var s=t(4164),a=t(1312),i=t(9022),l=t(4848);function o(e){const{className:n,previous:t,next:o}=e;return(0,l.jsxs)("nav",{className:(0,s.A)(n,"pagination-nav"),"aria-label":(0,a.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,l.jsx)(i.A,{...t,subLabel:(0,l.jsx)(a.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),o&&(0,l.jsx)(i.A,{...o,subLabel:(0,l.jsx)(a.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},7763:(e,n,t)=>{t.d(n,{A:()=>c});t(6540);var s=t(4164),a=t(5195);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var l=t(4848);const o="table-of-contents__link toc-highlight",r="table-of-contents__link--active";function c({className:e,...n}){return(0,l.jsx)("div",{className:(0,s.A)(i.tableOfContents,"thin-scrollbar",e),children:(0,l.jsx)(a.A,{...n,linkClassName:o,linkActiveClassName:r})})}},9022:(e,n,t)=>{t.d(n,{A:()=>l});t(6540);var s=t(4164),a=t(8774),i=t(4848);function l(e){const{permalink:n,title:t,subLabel:l,isNext:o}=e;return(0,i.jsxs)(a.A,{className:(0,s.A)("pagination-nav__link",o?"pagination-nav__link--next":"pagination-nav__link--prev"),to:n,children:[l&&(0,i.jsx)("div",{className:"pagination-nav__sublabel",children:l}),(0,i.jsx)("div",{className:"pagination-nav__label",children:t})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/1a64de69.22893b6e.js b/docs/assets/js/1a64de69.844e372c.js similarity index 69% rename from docs/assets/js/1a64de69.22893b6e.js rename to docs/assets/js/1a64de69.844e372c.js index 4e9a6ac1..e55cfef9 100644 --- a/docs/assets/js/1a64de69.22893b6e.js +++ b/docs/assets/js/1a64de69.844e372c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3645],{1694:a=>{a.exports=JSON.parse('{"tag":{"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho","allTagsPath":"/BharatMLStack/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/BharatMLStack/blog/tags/meesho","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3645],{1694:a=>{a.exports=JSON.parse('{"tag":{"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho","allTagsPath":"/BharatMLStack/blog/tags","count":5,"unlisted":false},"listMetadata":{"permalink":"/BharatMLStack/blog/tags/meesho","page":1,"postsPerPage":10,"totalPages":1,"totalCount":5,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/1f391b9e.4acd5995.js b/docs/assets/js/1f391b9e.4acd5995.js new file mode 100644 index 00000000..7ffe71ca --- /dev/null +++ b/docs/assets/js/1f391b9e.4acd5995.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6061],{1689:(e,n,t)=>{t.d(n,{A:()=>d});t(6540);var a=t(4164),i=t(4084),s=t(7559),r=t(7293),l=t(4848);function c({className:e}){return(0,l.jsx)(r.A,{type:"caution",title:(0,l.jsx)(i.Yh,{}),className:(0,a.A)(e,s.G.common.draftBanner),children:(0,l.jsx)(i.TT,{})})}var o=t(2234);function d({metadata:e}){const{unlisted:n,frontMatter:t}=e;return(0,l.jsxs)(l.Fragment,{children:[(n||t.unlisted)&&(0,l.jsx)(o.A,{}),t.draft&&(0,l.jsx)(c,{})]})}},2234:(e,n,t)=>{t.d(n,{A:()=>o});t(6540);var a=t(4164),i=t(7559),s=t(4084),r=t(7293),l=t(4848);function c({className:e}){return(0,l.jsx)(r.A,{type:"caution",title:(0,l.jsx)(s.Rc,{}),className:(0,a.A)(e,i.G.common.unlistedBanner),children:(0,l.jsx)(s.Uh,{})})}function o(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(s.AE,{}),(0,l.jsx)(c,{...e})]})}},4084:(e,n,t)=>{t.d(n,{AE:()=>c,Rc:()=>r,TT:()=>d,Uh:()=>l,Yh:()=>o});t(6540);var a=t(1312),i=t(5260),s=t(4848);function r(){return(0,s.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,s.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function c(){return(0,s.jsx)(i.A,{children:(0,s.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function o(){return(0,s.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,s.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}},5195:(e,n,t)=>{t.d(n,{A:()=>v});var a=t(6540),i=t(6342);function s(e){const n=e.map(e=>({...e,parentIndex:-1,children:[]})),t=Array(7).fill(-1);n.forEach((e,n)=>{const a=t.slice(2,e.level);e.parentIndex=Math.max(...a),t[e.level]=n});const a=[];return n.forEach(e=>{const{parentIndex:t,...i}=e;t>=0?n[t].children.push(i):a.push(i)}),a}function r({toc:e,minHeadingLevel:n,maxHeadingLevel:t}){return e.flatMap(e=>{const a=r({toc:e.children,minHeadingLevel:n,maxHeadingLevel:t});return function(e){return e.level>=n&&e.level<=t}(e)?[{...e,children:a}]:a})}function l(e){const n=e.getBoundingClientRect();return n.top===n.bottom?l(e.parentNode):n}function c(e,{anchorTopOffset:n}){const t=e.find(e=>l(e).top>=n);if(t){return function(e){return e.top>0&&e.bottom{e.current=n?0:document.querySelector(".navbar").clientHeight},[n]),e}function d(e){const n=(0,a.useRef)(void 0),t=o();(0,a.useEffect)(()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:i,minHeadingLevel:s,maxHeadingLevel:r}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),l=function({minHeadingLevel:e,maxHeadingLevel:n}){const t=[];for(let a=e;a<=n;a+=1)t.push(`h${a}.anchor`);return Array.from(document.querySelectorAll(t.join()))}({minHeadingLevel:s,maxHeadingLevel:r}),o=c(l,{anchorTopOffset:t.current}),d=e.find(e=>o&&o.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e));e.forEach(e=>{!function(e,t){t?(n.current&&n.current!==e&&n.current.classList.remove(i),e.classList.add(i),n.current=e):e.classList.remove(i)}(e,e===d)})}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}},[e,t])}var m=t(8774),u=t(4848);function f({toc:e,className:n,linkClassName:t,isChild:a}){return e.length?(0,u.jsx)("ul",{className:a?void 0:n,children:e.map(e=>(0,u.jsxs)("li",{children:[(0,u.jsx)(m.A,{to:`#${e.id}`,className:t??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,u.jsx)(f,{isChild:!0,toc:e.children,className:n,linkClassName:t})]},e.id))}):null}const h=a.memo(f);function v({toc:e,className:n="table-of-contents table-of-contents__left-border",linkClassName:t="table-of-contents__link",linkActiveClassName:l,minHeadingLevel:c,maxHeadingLevel:o,...m}){const f=(0,i.p)(),v=c??f.tableOfContents.minHeadingLevel,x=o??f.tableOfContents.maxHeadingLevel,g=function({toc:e,minHeadingLevel:n,maxHeadingLevel:t}){return(0,a.useMemo)(()=>r({toc:s(e),minHeadingLevel:n,maxHeadingLevel:t}),[e,n,t])}({toc:e,minHeadingLevel:v,maxHeadingLevel:x});return d((0,a.useMemo)(()=>{if(t&&l)return{linkClassName:t,linkActiveClassName:l,minHeadingLevel:v,maxHeadingLevel:x}},[t,l,v,x])),(0,u.jsx)(h,{toc:g,className:n,linkClassName:t,...m})}},7763:(e,n,t)=>{t.d(n,{A:()=>o});t(6540);var a=t(4164),i=t(5195);const s={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var r=t(4848);const l="table-of-contents__link toc-highlight",c="table-of-contents__link--active";function o({className:e,...n}){return(0,r.jsx)("div",{className:(0,a.A)(s.tableOfContents,"thin-scrollbar",e),children:(0,r.jsx)(i.A,{...n,linkClassName:l,linkActiveClassName:c})})}},7973:(e,n,t)=>{t.r(n),t.d(n,{default:()=>f});t(6540);var a=t(4164),i=t(5500),s=t(7559),r=t(1656),l=t(3253),c=t(7763),o=t(1689),d=t(4336);const m={mdxPageWrapper:"mdxPageWrapper_j9I6"};var u=t(4848);function f(e){const{content:n}=e,{metadata:t,assets:f}=n,{title:h,editUrl:v,description:x,frontMatter:g,lastUpdatedBy:p,lastUpdatedAt:j}=t,{keywords:A,wrapperClassName:b,hide_table_of_contents:L}=g,N=f.image??g.image,C=!!(v||j||p);return(0,u.jsx)(i.e3,{className:(0,a.A)(b??s.G.wrapper.mdxPages,s.G.page.mdxPage),children:(0,u.jsxs)(r.A,{children:[(0,u.jsx)(i.be,{title:h,description:x,keywords:A,image:N}),(0,u.jsx)("main",{className:"container container--fluid margin-vert--lg",children:(0,u.jsxs)("div",{className:(0,a.A)("row",m.mdxPageWrapper),children:[(0,u.jsxs)("div",{className:(0,a.A)("col",!L&&"col--8"),children:[(0,u.jsx)(o.A,{metadata:t}),(0,u.jsx)("article",{children:(0,u.jsx)(l.A,{children:(0,u.jsx)(n,{})})}),C&&(0,u.jsx)(d.A,{className:(0,a.A)("margin-top--sm",s.G.pages.pageFooterEditMetaRow),editUrl:v,lastUpdatedAt:j,lastUpdatedBy:p})]}),!L&&n.toc.length>0&&(0,u.jsx)("div",{className:"col col--2",children:(0,u.jsx)(c.A,{toc:n.toc,minHeadingLevel:g.toc_min_heading_level,maxHeadingLevel:g.toc_max_heading_level})})]})})]})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/1f391b9e.8e4379a0.js b/docs/assets/js/1f391b9e.8e4379a0.js deleted file mode 100644 index 76c76713..00000000 --- a/docs/assets/js/1f391b9e.8e4379a0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6061],{1689:(e,n,t)=>{t.d(n,{A:()=>d});t(6540);var a=t(4164),i=t(4084),s=t(7559),r=t(7293),l=t(4848);function c({className:e}){return(0,l.jsx)(r.A,{type:"caution",title:(0,l.jsx)(i.Yh,{}),className:(0,a.A)(e,s.G.common.draftBanner),children:(0,l.jsx)(i.TT,{})})}var o=t(2234);function d({metadata:e}){const{unlisted:n,frontMatter:t}=e;return(0,l.jsxs)(l.Fragment,{children:[(n||t.unlisted)&&(0,l.jsx)(o.A,{}),t.draft&&(0,l.jsx)(c,{})]})}},2234:(e,n,t)=>{t.d(n,{A:()=>o});t(6540);var a=t(4164),i=t(4084),s=t(7559),r=t(7293),l=t(4848);function c({className:e}){return(0,l.jsx)(r.A,{type:"caution",title:(0,l.jsx)(i.Rc,{}),className:(0,a.A)(e,s.G.common.unlistedBanner),children:(0,l.jsx)(i.Uh,{})})}function o(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(i.AE,{}),(0,l.jsx)(c,{...e})]})}},4084:(e,n,t)=>{t.d(n,{AE:()=>c,Rc:()=>r,TT:()=>d,Uh:()=>l,Yh:()=>o});t(6540);var a=t(1312),i=t(5260),s=t(4848);function r(){return(0,s.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,s.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function c(){return(0,s.jsx)(i.A,{children:(0,s.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function o(){return(0,s.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,s.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}},5195:(e,n,t)=>{t.d(n,{A:()=>v});var a=t(6540),i=t(6342);function s(e){const n=e.map((e=>({...e,parentIndex:-1,children:[]}))),t=Array(7).fill(-1);n.forEach(((e,n)=>{const a=t.slice(2,e.level);e.parentIndex=Math.max(...a),t[e.level]=n}));const a=[];return n.forEach((e=>{const{parentIndex:t,...i}=e;t>=0?n[t].children.push(i):a.push(i)})),a}function r({toc:e,minHeadingLevel:n,maxHeadingLevel:t}){return e.flatMap((e=>{const a=r({toc:e.children,minHeadingLevel:n,maxHeadingLevel:t});return function(e){return e.level>=n&&e.level<=t}(e)?[{...e,children:a}]:a}))}function l(e){const n=e.getBoundingClientRect();return n.top===n.bottom?l(e.parentNode):n}function c(e,{anchorTopOffset:n}){const t=e.find((e=>l(e).top>=n));if(t){return function(e){return e.top>0&&e.bottom{e.current=n?0:document.querySelector(".navbar").clientHeight}),[n]),e}function d(e){const n=(0,a.useRef)(void 0),t=o();(0,a.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:i,minHeadingLevel:s,maxHeadingLevel:r}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),l=function({minHeadingLevel:e,maxHeadingLevel:n}){const t=[];for(let a=e;a<=n;a+=1)t.push(`h${a}.anchor`);return Array.from(document.querySelectorAll(t.join()))}({minHeadingLevel:s,maxHeadingLevel:r}),o=c(l,{anchorTopOffset:t.current}),d=e.find((e=>o&&o.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,t){t?(n.current&&n.current!==e&&n.current.classList.remove(i),e.classList.add(i),n.current=e):e.classList.remove(i)}(e,e===d)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,t])}var m=t(8774),u=t(4848);function f({toc:e,className:n,linkClassName:t,isChild:a}){return e.length?(0,u.jsx)("ul",{className:a?void 0:n,children:e.map((e=>(0,u.jsxs)("li",{children:[(0,u.jsx)(m.A,{to:`#${e.id}`,className:t??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,u.jsx)(f,{isChild:!0,toc:e.children,className:n,linkClassName:t})]},e.id)))}):null}const h=a.memo(f);function v({toc:e,className:n="table-of-contents table-of-contents__left-border",linkClassName:t="table-of-contents__link",linkActiveClassName:l,minHeadingLevel:c,maxHeadingLevel:o,...m}){const f=(0,i.p)(),v=c??f.tableOfContents.minHeadingLevel,x=o??f.tableOfContents.maxHeadingLevel,g=function({toc:e,minHeadingLevel:n,maxHeadingLevel:t}){return(0,a.useMemo)((()=>r({toc:s(e),minHeadingLevel:n,maxHeadingLevel:t})),[e,n,t])}({toc:e,minHeadingLevel:v,maxHeadingLevel:x});return d((0,a.useMemo)((()=>{if(t&&l)return{linkClassName:t,linkActiveClassName:l,minHeadingLevel:v,maxHeadingLevel:x}}),[t,l,v,x])),(0,u.jsx)(h,{toc:g,className:n,linkClassName:t,...m})}},7763:(e,n,t)=>{t.d(n,{A:()=>o});t(6540);var a=t(4164),i=t(5195);const s={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var r=t(4848);const l="table-of-contents__link toc-highlight",c="table-of-contents__link--active";function o({className:e,...n}){return(0,r.jsx)("div",{className:(0,a.A)(s.tableOfContents,"thin-scrollbar",e),children:(0,r.jsx)(i.A,{...n,linkClassName:l,linkActiveClassName:c})})}},7973:(e,n,t)=>{t.r(n),t.d(n,{default:()=>f});t(6540);var a=t(4164),i=t(5500),s=t(7559),r=t(1656),l=t(3253),c=t(7763),o=t(1689),d=t(4336);const m={mdxPageWrapper:"mdxPageWrapper_j9I6"};var u=t(4848);function f(e){const{content:n}=e,{metadata:t,assets:f}=n,{title:h,editUrl:v,description:x,frontMatter:g,lastUpdatedBy:p,lastUpdatedAt:j}=t,{keywords:A,wrapperClassName:b,hide_table_of_contents:L}=g,N=f.image??g.image,C=!!(v||j||p);return(0,u.jsx)(i.e3,{className:(0,a.A)(b??s.G.wrapper.mdxPages,s.G.page.mdxPage),children:(0,u.jsxs)(r.A,{children:[(0,u.jsx)(i.be,{title:h,description:x,keywords:A,image:N}),(0,u.jsx)("main",{className:"container container--fluid margin-vert--lg",children:(0,u.jsxs)("div",{className:(0,a.A)("row",m.mdxPageWrapper),children:[(0,u.jsxs)("div",{className:(0,a.A)("col",!L&&"col--8"),children:[(0,u.jsx)(o.A,{metadata:t}),(0,u.jsx)("article",{children:(0,u.jsx)(l.A,{children:(0,u.jsx)(n,{})})}),C&&(0,u.jsx)(d.A,{className:(0,a.A)("margin-top--sm",s.G.pages.pageFooterEditMetaRow),editUrl:v,lastUpdatedAt:j,lastUpdatedBy:p})]}),!L&&n.toc.length>0&&(0,u.jsx)("div",{className:"col col--2",children:(0,u.jsx)(c.A,{toc:n.toc,minHeadingLevel:g.toc_min_heading_level,maxHeadingLevel:g.toc_max_heading_level})})]})})]})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/252a9097.3acfe41e.js b/docs/assets/js/252a9097.3acfe41e.js new file mode 100644 index 00000000..291cf393 --- /dev/null +++ b/docs/assets/js/252a9097.3acfe41e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4424],{248:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"inferflow/v1.0.0/architecture","title":"Architecture","description":"Inferflow is part of BharatMLStack, a graph-driven feature retrieval and model inference orchestration engine built in Go. It eliminates the need for custom feature retrieval code by using configurable DAG topologies to dynamically resolve entity relationships, fetch features from the Online Feature Store, and orchestrate model scoring \u2014 all driven by configuration stored in etcd.","source":"@site/docs/inferflow/v1.0.0/architecture.md","sourceDirName":"inferflow/v1.0.0","slug":"/inferflow/v1.0.0/architecture","permalink":"/BharatMLStack/inferflow/v1.0.0/architecture","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/inferflow/v1.0.0/architecture.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"Architecture","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"v1.0.0","permalink":"/BharatMLStack/inferflow/v1.0.0"},"next":{"title":"Key Functionalities","permalink":"/BharatMLStack/inferflow/v1.0.0/functionalities"}}');var i=r(4848),s=r(8453);const o={title:"Architecture",sidebar_position:1},l="BharatMLStack - Inferflow",c={},d=[{value:"Overview",id:"overview",level:2},{value:"High-Level Architecture",id:"high-level-architecture",level:2},{value:"Core Components",id:"core-components",level:2},{value:"1. gRPC Server",id:"1-grpc-server",level:3},{value:"2. DAG Topology Executor",id:"2-dag-topology-executor",level:3},{value:"3. Component Types",id:"3-component-types",level:3},{value:"4. ComponentMatrix \u2014 The 2D Result Matrix",id:"4-componentmatrix--the-2d-result-matrix",level:3},{value:"How the matrix evolves through the DAG",id:"how-the-matrix-evolves-through-the-dag",level:4},{value:"Matrix structure",id:"matrix-structure",level:4},{value:"5. Configuration Management (etcd)",id:"5-configuration-management-etcd",level:3},{value:"6. External Integrations",id:"6-external-integrations",level:3},{value:"Online Feature Store (OnFS)",id:"online-feature-store-onfs",level:4},{value:"Predator (Model Serving)",id:"predator-model-serving",level:4},{value:"Numerix (Compute Engine)",id:"numerix-compute-engine",level:4},{value:"Kafka (Inference Logging)",id:"kafka-inference-logging",level:4},{value:"Request Flow",id:"request-flow",level:2},{value:"Observability",id:"observability",level:2},{value:"Metrics (StatsD / Telegraf)",id:"metrics-statsd--telegraf",level:3},{value:"Logging",id:"logging",level:3},{value:"Deployment",id:"deployment",level:2},{value:"Docker",id:"docker",level:3},{value:"Supported Environments",id:"supported-environments",level:3},{value:"Configuration",id:"configuration",level:3},{value:"Target Users",id:"target-users",level:2},{value:"Benefits",id:"benefits",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"bharatmlstack---inferflow",children:"BharatMLStack - Inferflow"})}),"\n",(0,i.jsxs)(n.p,{children:["Inferflow is part of ",(0,i.jsx)(n.strong,{children:"BharatMLStack"}),", a graph-driven feature retrieval and model inference orchestration engine built in ",(0,i.jsx)(n.strong,{children:"Go"}),". It eliminates the need for custom feature retrieval code by using configurable DAG topologies to dynamically resolve entity relationships, fetch features from the Online Feature Store, and orchestrate model scoring \u2014 all driven by configuration stored in ",(0,i.jsx)(n.strong,{children:"etcd"}),"."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(n.p,{children:"In a typical ML serving pipeline, every new model requires bespoke code to:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Fetch features from multiple entities (user, product, user x category, etc.)"}),"\n",(0,i.jsx)(n.li,{children:"Infer intermediate entity relationships (e.g., extract category from product to fetch user x category data)"}),"\n",(0,i.jsx)(n.li,{children:"Orchestrate one or more model inference calls"}),"\n",(0,i.jsx)(n.li,{children:"Handle I/O, batching, and error propagation"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Inferflow abstracts all of this behind a ",(0,i.jsx)(n.strong,{children:"config-driven DAG executor"}),". Given a ",(0,i.jsx)(n.code,{children:"model_config_id"})," and context entities (e.g., ",(0,i.jsx)(n.code,{children:"userId"}),", ",(0,i.jsx)(n.code,{children:"productIds"}),"), it:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Loads a pre-defined feature retrieval and inference graph from etcd"}),"\n",(0,i.jsx)(n.li,{children:"Executes the graph to resolve entity relationships dynamically"}),"\n",(0,i.jsx)(n.li,{children:"Retrieves features from the Online Feature Store (OnFS) in parallel"}),"\n",(0,i.jsx)(n.li,{children:"Calls model serving endpoints (Predator) and compute services (Numerix)"}),"\n",(0,i.jsx)(n.li,{children:"Returns scored results as a structured response"}),"\n"]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"high-level-architecture",children:"High-Level Architecture"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Inferflow Architecture - DAG Topology Executor",src:r(7748).A+"",width:"2036",height:"1212"})}),"\n",(0,i.jsxs)(n.p,{children:["The diagram shows the internal DAG structure of Inferflow's topology executor. gRPC APIs (Pair, Point, Slate) feed into the DAG, where ",(0,i.jsx)(n.strong,{children:"Feature Init"})," bootstraps the ComponentMatrix. Feature components (FS User, FS Product, FS Region, FS User Cat, FS Region Scat) fetch features from ",(0,i.jsx)(n.strong,{children:"OnFS"})," in parallel and populate columns in the shared ",(0,i.jsx)(n.strong,{children:"2D Result Matrix"}),". Model components (Model A, Model B) call ",(0,i.jsx)(n.strong,{children:"Predator"})," for inference, and compute components call ",(0,i.jsx)(n.strong,{children:"Numerix"})," for operations like reranking. The entire DAG topology is driven by config loaded from ",(0,i.jsx)(n.strong,{children:"etcd"}),"."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"core-components",children:"Core Components"}),"\n",(0,i.jsx)(n.h3,{id:"1-grpc-server",children:"1. gRPC Server"}),"\n",(0,i.jsxs)(n.p,{children:["Inferflow exposes its APIs via a gRPC server, with HTTP health endpoints multiplexed on the same port using ",(0,i.jsx)(n.strong,{children:"cmux"}),". The server provides:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Inferflow API"})," \u2014 ",(0,i.jsx)(n.code,{children:"RetrieveModelScore"}),": entity-based feature retrieval and scoring"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Predict API"})," \u2014 ",(0,i.jsx)(n.code,{children:"InferPointWise"}),", ",(0,i.jsx)(n.code,{children:"InferPairWise"}),", ",(0,i.jsx)(n.code,{children:"InferSlateWise"}),": structured inference with targets, pairs, and slates"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"2-dag-topology-executor",children:"2. DAG Topology Executor"}),"\n",(0,i.jsxs)(n.p,{children:["The heart of Inferflow. Each model configuration defines a ",(0,i.jsx)(n.code,{children:"component_dependency"})," map that describes a Directed Acyclic Graph (DAG) of components."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Execution model:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Uses ",(0,i.jsx)(n.strong,{children:"Kahn's algorithm"})," for topological ordering"]}),"\n",(0,i.jsxs)(n.li,{children:["Components at the same level run ",(0,i.jsx)(n.strong,{children:"concurrently"})," in goroutines"]}),"\n",(0,i.jsxs)(n.li,{children:["All components share a mutable ",(0,i.jsx)(n.code,{children:"ComponentMatrix"})," (rows = entity IDs, columns = features/scores)"]}),"\n",(0,i.jsxs)(n.li,{children:["DAG topologies are ",(0,i.jsx)(n.strong,{children:"cached"})," using Murmur3 hashing with Ristretto cache"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Validation:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Cycle detection via in-degree analysis"}),"\n",(0,i.jsxs)(n.li,{children:["Component existence verification against the ",(0,i.jsx)(n.code,{children:"ComponentProvider"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"3-component-types",children:"3. Component Types"}),"\n",(0,i.jsx)(n.p,{children:"Inferflow defines four types of DAG components:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Component"}),(0,i.jsx)(n.th,{children:"Role"}),(0,i.jsx)(n.th,{children:"External Dependency"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"FeatureInitComponent"})}),(0,i.jsxs)(n.td,{children:["Root node \u2014 initializes the ",(0,i.jsx)(n.code,{children:"ComponentMatrix"})," with entity IDs and schema"]}),(0,i.jsx)(n.td,{children:"None"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"FeatureComponent"})}),(0,i.jsx)(n.td,{children:"Fetches features from the Online Feature Store for a specific entity type"}),(0,i.jsx)(n.td,{children:"OnFS (gRPC)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"PredatorComponent"})}),(0,i.jsx)(n.td,{children:"Calls model serving endpoints for inference scoring"}),(0,i.jsx)(n.td,{children:"Predator / Helix (gRPC)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"NumerixComponent"})}),(0,i.jsx)(n.td,{children:"Calls compute engine for operations like reranking"}),(0,i.jsx)(n.td,{children:"Numerix (gRPC)"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"4-componentmatrix--the-2d-result-matrix",children:"4. ComponentMatrix \u2014 The 2D Result Matrix"}),"\n",(0,i.jsx)(n.p,{children:"The ComponentMatrix is a shared, mutable 2D data structure that flows through the entire DAG. Every component reads from and writes to this matrix, progressively building a complete feature + score row for each entity."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"DAG Execution & 2D Matrix Flow",src:r(3066).A+"",width:"672",height:"778"})}),"\n",(0,i.jsx)(n.h4,{id:"how-the-matrix-evolves-through-the-dag",children:"How the matrix evolves through the DAG"}),"\n",(0,i.jsx)(n.p,{children:"The diagram above illustrates the three execution phases and how the 2D matrix grows at each stage:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Phase 1 \u2014 Feature Retrieval"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.strong,{children:"init"})," node creates an empty matrix with one row per target entity ID. Feature components then execute \u2014 first the top-level entities (entity A, entity B) fetch their features from OnFS and populate their columns (shown as colored blocks). Derived entities (entity C, D, E) resolve their keys from the already-populated columns and add more feature columns. At this point the matrix contains all feature data, with each color representing features from a different entity."]}),"\n",(0,i.jsxs)(n.p,{children:["The right side of the diagram shows the matrix being ",(0,i.jsx)(n.strong,{children:"decomposed"})," \u2014 feature columns from different entities are separated into per-model input groups, selecting only the features each model needs."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Phase 2 \u2014 Model Invocation"})}),"\n",(0,i.jsxs)(n.p,{children:["Model X and Model Y each receive their decomposed feature slices, call ",(0,i.jsx)(n.strong,{children:"Predator"})," for inference, and write score columns back into the matrix (shown as new colored columns appended to the right). Multiple models can run in parallel if they don't depend on each other's outputs."]}),"\n",(0,i.jsx)(n.p,{children:"The scores are then decomposed again to prepare inputs for the compute stage."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Phase 3 \u2014 Numerix Compute"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.strong,{children:"Score Comb"})," node takes score columns from both models, calls ",(0,i.jsx)(n.strong,{children:"Numerix"})," for a final compute operation (e.g., score combination, reranking), and writes the final score column (shown in dark red) into the matrix. The result is a complete row per entity with all features and all scores."]}),"\n",(0,i.jsx)(n.h4,{id:"matrix-structure",children:"Matrix structure"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Property"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"Rows"})}),(0,i.jsx)(n.td,{children:"One per target entity ID (e.g., each product being scored)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"String columns"})}),(0,i.jsx)(n.td,{children:"Human-readable values used in responses"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"Byte columns"})}),(0,i.jsx)(n.td,{children:"Binary-encoded feature values used for model inputs"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"Column naming"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"entity_label:feature_group:feature_name"})})]})]})]}),"\n",(0,i.jsx)(n.p,{children:"Each component only reads the columns it needs and writes to its own columns, enabling safe concurrent execution across independent branches of the DAG."}),"\n",(0,i.jsxs)(n.p,{children:["For slate-based APIs, a companion ",(0,i.jsx)(n.code,{children:"SlateData"})," structure holds per-slate matrices and scores, with ",(0,i.jsx)(n.code,{children:"slate_target_indices"})," mapping slates to rows in the main matrix."]}),"\n",(0,i.jsx)(n.h3,{id:"5-configuration-management-etcd",children:"5. Configuration Management (etcd)"}),"\n",(0,i.jsx)(n.p,{children:"Model configurations are stored in etcd and hot-reloaded via watchers:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Config paths"}),": ",(0,i.jsx)(n.code,{children:"/config/inferflow/services/"}),", ",(0,i.jsx)(n.code,{children:"/model-config"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Watch mechanism"}),": etcd watchers trigger ",(0,i.jsx)(n.code,{children:"ReloadModelConfigMapAndRegisterComponents"})," on any change"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"On reload"}),": Updates ",(0,i.jsx)(n.code,{children:"ConfigMap"}),", re-initializes feature schemas, and re-registers DAG components"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["This means new models or configuration changes go live ",(0,i.jsx)(n.strong,{children:"without redeployment"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"6-external-integrations",children:"6. External Integrations"}),"\n",(0,i.jsx)(n.h4,{id:"online-feature-store-onfs",children:"Online Feature Store (OnFS)"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["gRPC client calling ",(0,i.jsx)(n.code,{children:"FeatureService.RetrieveFeatures"})]}),"\n",(0,i.jsx)(n.li,{children:"Batched retrieval with configurable batch size and deadline"}),"\n",(0,i.jsxs)(n.li,{children:["Auth via ",(0,i.jsx)(n.code,{children:"CALLER_ID"})," and ",(0,i.jsx)(n.code,{children:"CALLER_TOKEN"})," metadata"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"predator-model-serving",children:"Predator (Model Serving)"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Uses ",(0,i.jsx)(n.code,{children:"helix-client"})," for model inference"]}),"\n",(0,i.jsxs)(n.li,{children:["Supports ",(0,i.jsx)(n.strong,{children:"percentage-based traffic routing"})," across multiple model endpoints"]}),"\n",(0,i.jsx)(n.li,{children:"Configurable calibration and batch sizing"}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"numerix-compute-engine",children:"Numerix (Compute Engine)"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Uses ",(0,i.jsx)(n.code,{children:"helix-client"})," Numerix client"]}),"\n",(0,i.jsxs)(n.li,{children:["RPC: ",(0,i.jsx)(n.code,{children:"NumerixService.Compute"})," with entity score data"]}),"\n",(0,i.jsx)(n.li,{children:"Used for compute operations like reranking"}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"kafka-inference-logging",children:"Kafka (Inference Logging)"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Async inference log publishing using ",(0,i.jsx)(n.code,{children:"segmentio/kafka-go"})]}),"\n",(0,i.jsxs)(n.li,{children:["Supports ",(0,i.jsx)(n.strong,{children:"Proto"}),", ",(0,i.jsx)(n.strong,{children:"Arrow"}),", and ",(0,i.jsx)(n.strong,{children:"Parquet"})," serialization formats"]}),"\n",(0,i.jsxs)(n.li,{children:["Configurable sampling via ",(0,i.jsx)(n.code,{children:"LoggingPerc"})," and user-based daily sampling"]}),"\n"]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"request-flow",children:"Request Flow"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"1. Client sends gRPC request with model_config_id + entity IDs\n \u2502\n2. Load ModelConfig from etcd-backed ConfigMap\n \u2502\n3. Adapt proto request \u2192 ComponentRequest\n (build ComponentMatrix with entity schema)\n \u2502\n4. Resolve DAG topology from component_dependency config\n \u2502\n5. Execute DAG (Kahn's algorithm, concurrent):\n \u2502\n \u251c\u2500 FeatureInitComponent: populate matrix with entity IDs + schema\n \u2502\n \u251c\u2500 FeatureComponents (parallel): fetch features from OnFS \u2192 fill matrix columns\n \u2502\n \u251c\u2500 PredatorComponent: build feature payloads from matrix \u2192 call model \u2192 write scores\n \u2502\n \u2514\u2500 NumerixComponent: read scores from matrix \u2192 call compute \u2192 write final scores\n \u2502\n6. Build response from matrix columns per ResponseConfig\n \u2502\n7. (Optional) Async Kafka logging of inference features and scores\n \u2502\n8. Return gRPC response to client\n"})}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"observability",children:"Observability"}),"\n",(0,i.jsx)(n.h3,{id:"metrics-statsd--telegraf",children:"Metrics (StatsD / Telegraf)"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Metric"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"inferflow.retrievemodelscore.request.total"})}),(0,i.jsx)(n.td,{children:"Total RetrieveModelScore requests"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"inferflow.retrievemodelscore.latency"})}),(0,i.jsx)(n.td,{children:"End-to-end latency"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"inferflow.retrievemodelscore.batch.size"})}),(0,i.jsx)(n.td,{children:"Batch size per request"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"predict.infer.request.total"})}),(0,i.jsx)(n.td,{children:"Total Predict API requests"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"predict.infer.latency"})}),(0,i.jsx)(n.td,{children:"Predict API latency"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"inferflow.component.execution.total"})}),(0,i.jsx)(n.td,{children:"Per-component execution count"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"inferflow.component.execution.latency"})}),(0,i.jsx)(n.td,{children:"Per-component latency"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"inferflow.component.execution.error"})}),(0,i.jsx)(n.td,{children:"Component-level errors"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"inferflow.component.feature.count"})}),(0,i.jsx)(n.td,{children:"Feature count per component"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"inferflow.external.api.request.total"})}),(0,i.jsx)(n.td,{children:"External API call count"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"inferflow.external.api.latency"})}),(0,i.jsx)(n.td,{children:"External API latency"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"inferflow.component.inmemorycache.request.total"})}),(0,i.jsx)(n.td,{children:"Cache hit/miss total"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"inferflow.component.inmemorycache.miss"})}),(0,i.jsx)(n.td,{children:"Cache misses"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"inferflow.logging.kafka_sent"})}),(0,i.jsx)(n.td,{children:"Kafka log messages sent"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"logging",children:"Logging"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Structured JSON logging via ",(0,i.jsx)(n.strong,{children:"zerolog"})]}),"\n",(0,i.jsx)(n.li,{children:"Configurable log levels"}),"\n"]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"deployment",children:"Deployment"}),"\n",(0,i.jsx)(n.h3,{id:"docker",children:"Docker"}),"\n",(0,i.jsx)(n.p,{children:"Inferflow ships as a multi-stage Docker image:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Builder"}),": Go 1.19 Alpine with optional Kafka support (librdkafka)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Runtime"}),": Debian 10 slim"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Build command"}),": ",(0,i.jsx)(n.code,{children:'go build -tags musl -ldflags "-extldflags -static" -o server cmd/${module}/main.go'})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"supported-environments",children:"Supported Environments"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Kubernetes (K8s)"}),"\n",(0,i.jsx)(n.li,{children:"Google Kubernetes Engine (GKE)"}),"\n",(0,i.jsx)(n.li,{children:"Amazon EKS"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"configuration",children:"Configuration"}),"\n",(0,i.jsx)(n.p,{children:"All configuration is driven via environment variables (loaded by Viper) and etcd. No config files are required at deployment time."}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"target-users",children:"Target Users"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"User"}),(0,i.jsx)(n.th,{children:"Role"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Data Scientists"}),(0,i.jsx)(n.td,{children:"Define model configs and feature retrieval graphs via config \u2014 no code needed"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ML Engineers"}),(0,i.jsx)(n.td,{children:"Onboard new models by updating etcd config; manage DAG topologies"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Backend Developers"}),(0,i.jsx)(n.td,{children:"Integrate via gRPC SDKs for real-time scoring in application services"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Platform Engineers"}),(0,i.jsx)(n.td,{children:"Deploy, scale, and monitor Inferflow clusters"})]})]})]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"benefits",children:"Benefits"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"No-code feature retrieval"})," \u2014 new models need only a config change, not custom code"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Feature consistency"})," \u2014 same graph-driven retrieval ensures identical features across experiments"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Faster iteration"})," \u2014 experiment with new models in minutes, not days"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Concurrent execution"})," \u2014 DAG components run in parallel for minimal latency"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Hot reloading"})," \u2014 model config changes via etcd go live without redeployment"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Multi-API support"})," \u2014 PointWise, PairWise, and SlateWise inference patterns out of the box"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Production-grade"})," \u2014 built in Go with gRPC, designed for millions of QPS"]}),"\n"]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,i.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,i.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,i.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,i.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},3066:(e,n,r)=>{r.d(n,{A:()=>t});const t=r.p+"assets/images/v1.0.0-inferflow-dag-matrix-0f13b51422587e6099cf4ee783844db1.png"},7748:(e,n,r)=>{r.d(n,{A:()=>t});const t=r.p+"assets/images/v1.0.0-inferflow-arch-bce54b3b4f7d3be68fa22dc204529f53.png"},8453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>l});var t=r(6540);const i={},s=t.createContext(i);function o(e){const n=t.useContext(s);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/2c62ead1.fc5c1b17.js b/docs/assets/js/2c62ead1.fc5c1b17.js new file mode 100644 index 00000000..83e25c6b --- /dev/null +++ b/docs/assets/js/2c62ead1.fc5c1b17.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5801],{1688:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>a,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"numerix/v1.0.0/functionalities","title":"Key Functionalities","description":"Overview","source":"@site/docs/numerix/v1.0.0/functionalities.md","sourceDirName":"numerix/v1.0.0","slug":"/numerix/v1.0.0/functionalities","permalink":"/BharatMLStack/numerix/v1.0.0/functionalities","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/numerix/v1.0.0/functionalities.md","tags":[],"version":"current","sidebarPosition":3,"frontMatter":{"title":"Key Functionalities","sidebar_position":3},"sidebar":"tutorialSidebar","previous":{"title":"Benchmarks","permalink":"/BharatMLStack/numerix/v1.0.0/benchmarks"},"next":{"title":"Release Notes","permalink":"/BharatMLStack/numerix/v1.0.0/release-notes"}}');var r=n(4848),t=n(8453);const l={title:"Key Functionalities",sidebar_position:3},o="Numerix \u2014 Key Functionalities",a={},c=[{value:"Overview",id:"overview",level:2},{value:"\ud83d\ude80 Core Capabilities",id:"-core-capabilities",level:2},{value:"Expression Evaluation",id:"expression-evaluation",level:3},{value:"Input Formats",id:"input-formats",level:3},{value:"Request Patterns",id:"request-patterns",level:3},{value:"\ud83c\udfaf Developer Experience",id:"-developer-experience",level:2},{value:"gRPC Service",id:"grpc-service",level:3},{value:"Example Call (grpcurl)",id:"example-call-grpcurl",level:3},{value:"\ud83d\udcca Observability",id:"-observability",level:2},{value:"\u2699\ufe0f Configuration & Registry",id:"\ufe0f-configuration--registry",level:2},{value:"\ud83e\uddea Example Scenarios",id:"-example-scenarios",level:2},{value:"Batched evaluation",id:"batched-evaluation",level:3},{value:"Mixed input formats",id:"mixed-input-formats",level:3},{value:"\ud83d\udd27 Tuning Knobs",id:"-tuning-knobs",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const i={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(i.header,{children:(0,r.jsx)(i.h1,{id:"numerix--key-functionalities",children:"Numerix \u2014 Key Functionalities"})}),"\n",(0,r.jsx)(i.h2,{id:"overview",children:"Overview"}),"\n",(0,r.jsxs)(i.p,{children:["Numerix evaluates mathematical expressions over feature matrices with a simple, low-latency gRPC surface. Each request references a ",(0,r.jsx)(i.code,{children:"compute_id"}),"; Numerix resolves a postfix expression, maps variables to input columns, and evaluates it over fp32/fp64 vectors with compiler-assisted SIMD."]}),"\n",(0,r.jsx)(i.h2,{id:"-core-capabilities",children:"\ud83d\ude80 Core Capabilities"}),"\n",(0,r.jsx)(i.h3,{id:"expression-evaluation",children:"Expression Evaluation"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"Postfix execution"}),": Linear-time, stack-based evaluation over aligned vectors."]}),"\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"Vectorized math"}),": Compiler autovectorization (NEON/SVE on ARM, SSE/AVX on x86) \u2014 no handwritten intrinsics."]}),"\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"Typed compute"}),": Inputs converted to ",(0,r.jsx)(i.code,{children:"fp32"})," or ",(0,r.jsx)(i.code,{children:"fp64"})," for predictable performance."]}),"\n"]}),"\n",(0,r.jsx)(i.h3,{id:"input-formats",children:"Input Formats"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"Strings"}),": Easy-to-produce feature values (converted internally)."]}),"\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"Bytes"}),": Efficient wire format for high-throughput paths."]}),"\n"]}),"\n",(0,r.jsx)(i.h3,{id:"request-patterns",children:"Request Patterns"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"Single entity or batch"}),": Multiple ",(0,r.jsx)(i.code,{children:"entity_scores"})," per call."]}),"\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"Schema-driven"}),": Column order in ",(0,r.jsx)(i.code,{children:"schema"})," drives variable mapping in expressions."]}),"\n"]}),"\n",(0,r.jsx)(i.h2,{id:"-developer-experience",children:"\ud83c\udfaf Developer Experience"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"gRPC API"}),": Simple single RPC \u2014 ",(0,r.jsx)(i.code,{children:"Numerix/Compute"}),"."]}),"\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"Protobuf schema"}),": Language-agnostic client generation."]}),"\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"Deterministic behavior"}),": No parsing at request time; expression resolved from registry."]}),"\n"]}),"\n",(0,r.jsx)(i.h3,{id:"grpc-service",children:"gRPC Service"}),"\n",(0,r.jsx)(i.pre,{children:(0,r.jsx)(i.code,{className:"language-protobuf",children:"service Numerix {\n rpc Compute(NumerixRequestProto) returns (NumerixResponseProto);\n}\n"})}),"\n",(0,r.jsx)(i.h3,{id:"example-call-grpcurl",children:"Example Call (grpcurl)"}),"\n",(0,r.jsx)(i.pre,{children:(0,r.jsx)(i.code,{className:"language-bash",children:'grpcurl -plaintext \\\n -import-path ./numerix/src/protos/proto \\\n -proto numerix.proto \\\n -d \'{\n "entityScoreData": {\n "schema": ["feature1", "feature2"],\n "entityScores": [ { "stringData": { "values": ["1.0", "2.0"] } } ],\n "computeId": "1001",\n "dataType": "fp32"\n }\n }\' \\\n localhost:8080 numerix.Numerix/Compute\n'})}),"\n",(0,r.jsx)(i.h2,{id:"-observability",children:"\ud83d\udcca Observability"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"Datadog/DogStatsD"}),": Latency (P50/P95/P99), RPS, error rate via UDP client."]}),"\n",(0,r.jsxs)(i.li,{children:["Optional ",(0,r.jsx)(i.code,{children:"/metrics"})," endpoint for local/adhoc debugging."]}),"\n"]}),"\n",(0,r.jsx)(i.h2,{id:"\ufe0f-configuration--registry",children:"\u2699\ufe0f Configuration & Registry"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"etcd registry"}),": ",(0,r.jsx)(i.code,{children:"compute_id (int) \u2192 postfix expression"})," mapping."]}),"\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"Environment-driven config"}),": endpoints, timeouts, sampling rate."]}),"\n"]}),"\n",(0,r.jsx)(i.h2,{id:"-example-scenarios",children:"\ud83e\uddea Example Scenarios"}),"\n",(0,r.jsx)(i.h3,{id:"batched-evaluation",children:"Batched evaluation"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsxs)(i.li,{children:["Submit multiple entities in one call to reduce RPC overhead; evaluate the same ",(0,r.jsx)(i.code,{children:"compute_id"})," across all rows."]}),"\n"]}),"\n",(0,r.jsx)(i.h3,{id:"mixed-input-formats",children:"Mixed input formats"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsx)(i.li,{children:"Start with string inputs for ease; migrate to bytes for performance without changing the expression or API."}),"\n"]}),"\n",(0,r.jsx)(i.h2,{id:"-tuning-knobs",children:"\ud83d\udd27 Tuning Knobs"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"Data type"}),": choose ",(0,r.jsx)(i.code,{children:"fp32"})," (speed) vs ",(0,r.jsx)(i.code,{children:"fp64"})," (precision)."]}),"\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"Batch size"}),": tune number of entities per call for your p99 vs throughput goals."]}),"\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.strong,{children:"Sampling rate"}),": adjust Datadog metric sampling to balance signal vs cost."]}),"\n"]}),"\n",(0,r.jsx)(i.hr,{}),"\n",(0,r.jsx)(i.h2,{id:"contributing",children:"Contributing"}),"\n",(0,r.jsxs)(i.p,{children:["We welcome contributions from the community! Please see our ",(0,r.jsx)(i.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,r.jsx)(i.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsxs)(i.li,{children:["\ud83d\udcac ",(0,r.jsx)(i.strong,{children:"Discord"}),": Join our ",(0,r.jsx)(i.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,r.jsxs)(i.li,{children:["\ud83d\udc1b ",(0,r.jsx)(i.strong,{children:"Issues"}),": Report bugs and request features on ",(0,r.jsx)(i.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,r.jsxs)(i.li,{children:["\ud83d\udce7 ",(0,r.jsx)(i.strong,{children:"Email"}),": Contact us at ",(0,r.jsx)(i.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,r.jsx)(i.h2,{id:"license",children:"License"}),"\n",(0,r.jsxs)(i.p,{children:["BharatMLStack is open-source software licensed under the ",(0,r.jsx)(i.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,r.jsx)(i.hr,{}),"\n",(0,r.jsx)("div",{align:"center",children:(0,r.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,r.jsx)("div",{align:"center",children:(0,r.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function u(e={}){const{wrapper:i}={...(0,t.R)(),...e.components};return i?(0,r.jsx)(i,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,i,n)=>{n.d(i,{R:()=>l,x:()=>o});var s=n(6540);const r={},t=s.createContext(r);function l(e){const i=s.useContext(t);return s.useMemo(function(){return"function"==typeof e?e(i):{...i,...e}},[i,e])}function o(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),s.createElement(t.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/2d865531.3ec70534.js b/docs/assets/js/2d865531.3ec70534.js new file mode 100644 index 00000000..d2d66fc0 --- /dev/null +++ b/docs/assets/js/2d865531.3ec70534.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9197],{4153:t=>{t.exports=JSON.parse('{"authors":[{"name":"Adarsha Das","title":"Senior Architect @ Meesho","url":"https://github.com/a0d00kc","imageURL":"https://github.com/a0d00kc.png","key":"adarsha","page":null,"count":3},{"name":"Aditya Kumar","title":"Lead Software Engineer @ Meesho","url":"https://github.com/Adit2607","imageURL":"https://github.com/Adit2607.png","key":"aditya","page":null,"count":2},{"name":"Jigar Dave","title":"Lead Software Engineer @ Meesho","url":"https://github.com/jigarpatel26","imageURL":"https://github.com/jigarpatel26.png","key":"jigar","page":null,"count":2},{"name":"Jaya Kumar","title":"Lead ML Engineer @ Meesho","url":"https://github.com/jayakommuru","imageURL":"https://github.com/jayakommuru.png","key":"jaya","page":null,"count":3},{"name":"Bhawani Singh","title":"Architect @ Meesho","url":"https://github.com/singh-bhawani","imageURL":"https://github.com/singh-bhawani.png","key":"bhawani","page":null,"count":2},{"name":"Mohit Kumar","title":"SDE-III @ Meesho","url":"https://github.com/kmohit00","imageURL":"https://github.com/kmohit00.png","key":"mohit","page":null,"count":0}]}')}}]); \ No newline at end of file diff --git a/docs/assets/js/2d865531.a5005531.js b/docs/assets/js/2d865531.a5005531.js deleted file mode 100644 index f959c03e..00000000 --- a/docs/assets/js/2d865531.a5005531.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9197],{4153:t=>{t.exports=JSON.parse('{"authors":[{"name":"Adarsha Das","title":"Senior Architect @ Meesho","url":"https://github.com/a0d00kc","imageURL":"https://github.com/a0d00kc.png","key":"adarsha","page":null,"count":1},{"name":"Aditya Kumar","title":"SDE-III @ Meesho","url":"https://github.com/Adit2607","imageURL":"https://github.com/Adit2607.png","key":"aditya","page":null,"count":1},{"name":"Jigar Dave","title":"SDE-IV @ Meesho","url":"https://github.com/jigarpatel26","imageURL":"https://github.com/jigarpatel26.png","key":"jigar","page":null,"count":1},{"name":"Jaya Kumar","title":"MLE-III @ Meesho","url":"https://github.com/jayakommuru","imageURL":"https://github.com/jayakommuru.png","key":"jaya","page":null,"count":0},{"name":"Bhawani Singh","title":"SDE-IV @ Meesho","url":"https://github.com/singh-bhawani","imageURL":"https://github.com/singh-bhawani.png","key":"bhawani","page":null,"count":1},{"name":"Mohit Kumar","title":"SDE-III @ Meesho","url":"https://github.com/kmohit00","imageURL":"https://github.com/kmohit00.png","key":"mohit","page":null,"count":0}]}')}}]); \ No newline at end of file diff --git a/docs/assets/js/3216e812.877aa30c.js b/docs/assets/js/3216e812.877aa30c.js new file mode 100644 index 00000000..0c4e114e --- /dev/null +++ b/docs/assets/js/3216e812.877aa30c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4771],{1494:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"v1.0.0","description":"Numerix v1.0.0","slug":"/numerix/v1.0.0","permalink":"/BharatMLStack/numerix/v1.0.0","sidebar":"tutorialSidebar","navigation":{"previous":{"title":"Numerix","permalink":"/BharatMLStack/category/numerix"},"next":{"title":"Architecture","permalink":"/BharatMLStack/numerix/v1.0.0/architecture"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/393be207.81b456e5.js b/docs/assets/js/393be207.6e979fd2.js similarity index 80% rename from docs/assets/js/393be207.81b456e5.js rename to docs/assets/js/393be207.6e979fd2.js index 044303c5..ff548d9e 100644 --- a/docs/assets/js/393be207.81b456e5.js +++ b/docs/assets/js/393be207.6e979fd2.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4134],{591:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>c,default:()=>l,frontMatter:()=>s,metadata:()=>a,toc:()=>d});const a=JSON.parse('{"type":"mdx","permalink":"/BharatMLStack/markdown-page","source":"@site/src/pages/markdown-page.md","title":"Markdown page example","description":"You don\'t need React to write simple standalone pages.","frontMatter":{"title":"Markdown page example"},"unlisted":false}');var o=n(4848),r=n(8453);const s={title:"Markdown page example"},c="Markdown page example",p={},d=[];function i(e){const t={h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"markdown-page-example",children:"Markdown page example"})}),"\n",(0,o.jsx)(t.p,{children:"You don't need React to write simple standalone pages."})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(i,{...e})}):i(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var a=n(6540);const o={},r=a.createContext(o);function s(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4134],{591:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>c,default:()=>l,frontMatter:()=>s,metadata:()=>a,toc:()=>d});const a=JSON.parse('{"type":"mdx","permalink":"/BharatMLStack/markdown-page","source":"@site/src/pages/markdown-page.md","title":"Markdown page example","description":"You don\'t need React to write simple standalone pages.","frontMatter":{"title":"Markdown page example"},"unlisted":false}');var o=n(4848),r=n(8453);const s={title:"Markdown page example"},c="Markdown page example",p={},d=[];function i(e){const t={h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"markdown-page-example",children:"Markdown page example"})}),"\n",(0,o.jsx)(t.p,{children:"You don't need React to write simple standalone pages."})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(i,{...e})}):i(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var a=n(6540);const o={},r=a.createContext(o);function s(e){const t=a.useContext(r);return a.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/3980073a.4ab85476.js b/docs/assets/js/3980073a.43116f8b.js similarity index 71% rename from docs/assets/js/3980073a.4ab85476.js rename to docs/assets/js/3980073a.43116f8b.js index a2b5d33b..482c5b6e 100644 --- a/docs/assets/js/3980073a.4ab85476.js +++ b/docs/assets/js/3980073a.43116f8b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[940],{3840:t=>{t.exports=JSON.parse('{"tag":{"label":"interaction-store","permalink":"/BharatMLStack/blog/tags/interaction-store","allTagsPath":"/BharatMLStack/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/BharatMLStack/blog/tags/interaction-store","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[940],{3840:t=>{t.exports=JSON.parse('{"tag":{"label":"interaction-store","permalink":"/BharatMLStack/blog/tags/interaction-store","allTagsPath":"/BharatMLStack/blog/tags","count":2,"unlisted":false},"listMetadata":{"permalink":"/BharatMLStack/blog/tags/interaction-store","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/3aeb33c7.b4a8c40f.js b/docs/assets/js/3aeb33c7.b4a8c40f.js new file mode 100644 index 00000000..854f0ff5 --- /dev/null +++ b/docs/assets/js/3aeb33c7.b4a8c40f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[974],{5969:e=>{e.exports=JSON.parse('{"permalink":"/BharatMLStack/blog/post-five","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-five/index.md","source":"@site/blog/bharatmlstack-history/post-five/index.md","title":"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale","description":"BharatMLStack","date":"2025-06-02T00:00:00.000Z","tags":[{"inline":true,"label":"llm","permalink":"/BharatMLStack/blog/tags/llm"},{"inline":true,"label":"vllm","permalink":"/BharatMLStack/blog/tags/vllm"},{"inline":true,"label":"tensorrt-llm","permalink":"/BharatMLStack/blog/tags/tensorrt-llm"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"},{"inline":true,"label":"bharatmlstack","permalink":"/BharatMLStack/blog/tags/bharatmlstack"}],"readingTime":4.93,"hasTruncateMarker":false,"authors":[{"name":"Jaya Kumar","title":"Lead ML Engineer @ Meesho","url":"https://github.com/jayakommuru","imageURL":"https://github.com/jayakommuru.png","key":"jaya","page":null}],"frontMatter":{"slug":"post-five","title":"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale","authors":["jaya"],"date":"2025-6-2","tags":["llm","vllm","tensorrt-llm","mlplatform","meesho","bharatmlstack"]},"unlisted":false,"nextItem":{"title":"Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving","permalink":"/BharatMLStack/blog/post-three"}}')},7309:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>h,contentTitle:()=>d,default:()=>o,frontMatter:()=>r,metadata:()=>n,toc:()=>c});var n=i(5969),s=i(4848),l=i(8453);const r={slug:"post-five",title:"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale",authors:["jaya"],date:"2025-6-2",tags:["llm","vllm","tensorrt-llm","mlplatform","meesho","bharatmlstack"]},d=void 0,h={authorsImageUrls:[void 0]},c=[{value:"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale",id:"llm-inference-optimization-techniques-engineering-sub-second-latency-at-scale",level:2},{value:"1. Advanced Memory Management: Paged & Prefix KV Caching",id:"1-advanced-memory-management-paged--prefix-kv-caching",level:2},{value:"Paged KV caching",id:"paged-kv-caching",level:3},{value:"KV cache quantization",id:"kv-cache-quantization",level:3},{value:"Prefix caching (the "voice bot" optimizer)",id:"prefix-caching-the-voice-bot-optimizer",level:3},{value:"2. Aggressive Quantization (INT4 AWQ & FP8)",id:"2-aggressive-quantization-int4-awq--fp8",level:2},{value:"INT4 AWQ (Activation-aware Weight Quantization)",id:"int4-awq-activation-aware-weight-quantization",level:3},{value:"FP8 precision",id:"fp8-precision",level:3},{value:"3. Kernel Fusion & Custom Plugins",id:"3-kernel-fusion--custom-plugins",level:2},{value:"4. Inflight (Continuous) Batching",id:"4-inflight-continuous-batching",level:2},{value:"5. Parallelism Strategies: Scaling Beyond One GPU",id:"5-parallelism-strategies-scaling-beyond-one-gpu",level:2},{value:"6. Speculative Decoding",id:"6-speculative-decoding",level:2},{value:"Few Benchmarks",id:"few-benchmarks",level:2},{value:"Search query rewriting",id:"search-query-rewriting",level:3},{value:"Voice bot query",id:"voice-bot-query",level:3},{value:"Conclusion",id:"conclusion",level:2}];function a(e){const t={h2:"h2",h3:"h3",img:"img",li:"li",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,l.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"BharatMLStack",src:i(9200).A+"",width:"1396",height:"460"})}),"\n",(0,s.jsx)(t.h2,{id:"llm-inference-optimization-techniques-engineering-sub-second-latency-at-scale",children:"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale"}),"\n",(0,s.jsx)(t.p,{children:"Raw execution of Large Language Models is inherently expensive and memory-intensive. To achieve sub-second latency and high throughput, we implement a multi-layered optimization strategy that targets the entire inference stack\u2014from memory management to kernel execution."}),"\n",(0,s.jsx)(t.h2,{id:"1-advanced-memory-management-paged--prefix-kv-caching",children:"1. Advanced Memory Management: Paged & Prefix KV Caching"}),"\n",(0,s.jsx)(t.p,{children:"The most significant bottleneck in LLM inference is not always compute, but memory bandwidth\u2014specifically managing the Key-Value (KV) cache."}),"\n",(0,s.jsx)(t.h3,{id:"paged-kv-caching",children:"Paged KV caching"}),"\n",(0,s.jsxs)(t.p,{children:["Standard caching suffers from fragmentation. We use ",(0,s.jsx)(t.strong,{children:"Paged KV caching"}),", which operates similarly to an operating system's virtual memory: the KV cache is divided into non-contiguous blocks. This lets us serve larger batch sizes without running out of memory."]}),"\n",(0,s.jsx)(t.h3,{id:"kv-cache-quantization",children:"KV cache quantization"}),"\n",(0,s.jsxs)(t.p,{children:["To further maximize available memory, we implement ",(0,s.jsx)(t.strong,{children:"KV cache quantization"})," (e.g., FP8). By compressing stored attention keys and values from 16-bit to 8-bit, we nearly double the effective context window capacity of the GPU, allowing longer conversations or larger batches without materially degrading quality."]}),"\n",(0,s.jsx)(t.h3,{id:"prefix-caching-the-voice-bot-optimizer",children:'Prefix caching (the "voice bot" optimizer)'}),"\n",(0,s.jsxs)(t.p,{children:['For use cases like GenAI voice bots where the system prompt (e.g., "You are a helpful assistant...") is static across thousands of requests, we enable ',(0,s.jsx)(t.strong,{children:"prefix caching"}),"."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Impact"}),": By reusing pre-computed KV states for common prefixes, we achieve a cache hit rate of ~90%. This reduces ",(0,s.jsx)(t.strong,{children:"Time To First Token (TTFT)"})," by skipping redundant computation of the system prompt."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"2-aggressive-quantization-int4-awq--fp8",children:"2. Aggressive Quantization (INT4 AWQ & FP8)"}),"\n",(0,s.jsx)(t.p,{children:"Running models in their native 16-bit precision (BF16) restricts maximum batch size and throughput. We use quantization to shrink model weights without sacrificing accuracy."}),"\n",(0,s.jsx)(t.h3,{id:"int4-awq-activation-aware-weight-quantization",children:"INT4 AWQ (Activation-aware Weight Quantization)"}),"\n",(0,s.jsxs)(t.p,{children:["For the Llama 3 family, we use ",(0,s.jsx)(t.strong,{children:"AWQ"})," to compress weights to 4 bits. This reduces model size by ~75%, allowing larger models to fit into L4 GPU memory and significantly improving token generation speed."]}),"\n",(0,s.jsx)(t.h3,{id:"fp8-precision",children:"FP8 precision"}),"\n",(0,s.jsxs)(t.p,{children:["For NVIDIA Hopper (H100) architectures, we are exploring ",(0,s.jsx)(t.strong,{children:"FP8 quantization"}),", leveraging native FP8 tensor cores to accelerate matrix multiplications while maintaining a higher dynamic range than integer quantization."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Verification"}),": We validate quantized models by comparing dot-product similarity of embeddings against the FP16 baseline, consistently achieving ",(0,s.jsx)(t.strong,{children:">99% similarity"}),"."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"3-kernel-fusion--custom-plugins",children:"3. Kernel Fusion & Custom Plugins"}),"\n",(0,s.jsx)(t.p,{children:"To minimize overhead from launching thousands of small GPU operations, we fuse them into monolithic kernels using NVIDIA TensorRT plugins."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Flash attention & FMHA"}),": We enable ",(0,s.jsx)(t.strong,{children:"Fused Multi-Head Attention (FMHA)"})," combined with flash attention to reduce memory reads/writes."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"GEMM plugins"}),": We use specialized ",(0,s.jsx)(t.strong,{children:"GEMM"})," plugins to accelerate transformer linear layers."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Removing input padding"}),": Instead of padding short sequences to match the longest, we remove input padding so the GPU processes only valid tokens."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"4-inflight-continuous-batching",children:"4. Inflight (Continuous) Batching"}),"\n",(0,s.jsx)(t.p,{children:"Traditional static batching waits for all requests in a batch to finish before returning results\u2014so one long response delays everyone else."}),"\n",(0,s.jsxs)(t.p,{children:["We implement ",(0,s.jsx)(t.strong,{children:"inflight batching"}),": as soon as one request completes, its slot is freed and filled by a new request from the queue. This keeps GPUs saturated and decouples latency of short queries from long ones."]}),"\n",(0,s.jsx)(t.h2,{id:"5-parallelism-strategies-scaling-beyond-one-gpu",children:"5. Parallelism Strategies: Scaling Beyond One GPU"}),"\n",(0,s.jsx)(t.p,{children:"For large models (e.g., 70B+ parameters) that cannot fit into the VRAM of a single GPU, we use parallelism strategies."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Tensor parallelism (TP)"}),": Split weight matrices across multiple GPUs (e.g., 4\xd7 L4 or 8\xd7 A100). Each GPU computes a shard and outputs are reduced at every layer."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Pipeline parallelism (PP)"}),": Split model layers across GPUs to pipeline compute (e.g., while one GPU computes later layers for Request A, another starts early layers for Request B)."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"6-speculative-decoding",children:"6. Speculative Decoding"}),"\n",(0,s.jsxs)(t.p,{children:["To reduce inter-token latency (ITL), we explore ",(0,s.jsx)(t.strong,{children:"speculative decoding"}),"."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Mechanism"}),': A smaller, faster "draft" model speculatively generates a short token sequence (e.g., 5 tokens).']}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Verification"}),": The larger target model verifies those tokens in one parallel forward pass. If correct, we effectively generate multiple tokens per large-model step; if not, we discard and regenerate. This is effective for predictable text, improving perceived generation speed."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"few-benchmarks",children:"Few Benchmarks"}),"\n",(0,s.jsx)(t.p,{children:"Below are a couple of representative use cases and performance numbers."}),"\n",(0,s.jsx)(t.h3,{id:"search-query-rewriting",children:"Search query rewriting"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"LLM"}),": Fine-tuned llama-3.2-1B"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Input & output token length"}),": ~10\u201320"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Response type"}),": Non-streaming"]}),"\n"]}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Inference runtime"}),(0,s.jsx)(t.th,{children:"Hardware"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Max requests/sec"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Max p99 latency"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{children:"4 \xd7 L4 GPUs (multi-GPU)"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1000"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"95 ms"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{children:"1 \xd7 A100 40 GB GPU"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1000"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"69 ms"})]})]})]}),"\n",(0,s.jsx)(t.h3,{id:"voice-bot-query",children:"Voice bot query"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"LLM"}),": Llama-3.1-8B"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Input token length"}),": ~1900\u20132000"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Output token length"}),": ~200"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Response type"}),": Streaming"]}),"\n"]}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Inference runtime"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Concurrency"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"p99 TTFT (ms)"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"p99 ITL (ms)"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Token throughput (tokens/sec)"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Request throughput (req/sec)"}),(0,s.jsx)(t.th,{children:"Hardware"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"36.27"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"22.78"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"45.66"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"0.23"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"2"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"49.81"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"23.21"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"89.37"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"0.45"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"4"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"55.33"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"36.62"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"153.39"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"0.78"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"8"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"66.5"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"39.11"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"279.88"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1.47"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"16"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"131.8"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"30.39"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"547.8"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"2.77"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"32"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"277.22"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"48.02"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"925.7"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"4.78"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"64"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"498.52"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"71.62"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1,164.40"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"6.2"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"128"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"677.31"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"120.37"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1,445.18"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"7.69"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"256"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1,926.31"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"216.88"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1,600.81"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"8.52"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"21.17"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"9.24"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"130.05"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"0.68"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"2"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"25.78"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"9.21"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"264.5"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1.35"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"4"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"28.52"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"10.99"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"437.69"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"2.27"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"8"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"34.4"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"12.61"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"760.49"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"3.96"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"16"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"68.03"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"14.32"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1,343.80"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"7.01"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"32"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"185.96"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"16.82"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"2,287.30"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"11.92"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"64"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"136.87"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"21.17"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"3,625.22"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"18.89"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"128"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"463.78"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"34.15"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"4,456.51"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"23.24"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"256"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"890.12"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"59.18"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"5,188.24"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"27.05"}),(0,s.jsx)(t.td,{children:"A100"})]})]})]}),"\n",(0,s.jsx)(t.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,s.jsx)(t.p,{children:"High-performance LLM inference is fundamentally a systems engineering problem: memory efficiency, kernel execution, batching strategy, and parallelism determine real-world latency and throughput. Techniques such as paged KV caching, aggressive quantization, kernel fusion, and inflight batching improve GPU utilization while reducing latency and memory pressure."}),"\n",(0,s.jsx)(t.p,{children:"These optimizations enable the platform to deliver sub-second responses, sustain high concurrency, and efficiently serve both lightweight and long-context workloads. By continuously optimizing across the full inference stack, we keep LLM serving scalable, cost-efficient, and production-ready for real-time AI applications."})]})}function o(e={}){const{wrapper:t}={...(0,l.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},8453:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>d});var n=i(6540);const s={},l=n.createContext(s);function r(e){const t=n.useContext(l);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(l.Provider,{value:t},e.children)}},9200:(e,t,i)=>{i.d(t,{A:()=>n});const n=i.p+"assets/images/bms-7399e8796d2cd24617c432518ce3f312.png"}}]); \ No newline at end of file diff --git a/docs/assets/js/4137b431.2e5cd4ca.js b/docs/assets/js/4137b431.2e5cd4ca.js deleted file mode 100644 index 125ba260..00000000 --- a/docs/assets/js/4137b431.2e5cd4ca.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6054],{4019:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"category","label":"Online Feature Store","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"v1.0.0","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Architecture","href":"/BharatMLStack/online-feature-store/v1.0.0/architecture","docId":"online-feature-store/v1.0.0/architecture","unlisted":false},{"type":"link","label":"Data Formats","href":"/BharatMLStack/online-feature-store/v1.0.0/data-formats","docId":"online-feature-store/v1.0.0/data-formats","unlisted":false},{"type":"link","label":"Benchmarks","href":"/BharatMLStack/online-feature-store/v1.0.0/benchmarks","docId":"online-feature-store/v1.0.0/benchmarks","unlisted":false},{"type":"link","label":"Key Functionalities","href":"/BharatMLStack/online-feature-store/v1.0.0/functionalities","docId":"online-feature-store/v1.0.0/functionalities","unlisted":false},{"type":"link","label":"Release Notes","href":"/BharatMLStack/online-feature-store/v1.0.0/release-notes","docId":"online-feature-store/v1.0.0/release-notes","unlisted":false}],"href":"/BharatMLStack/online-feature-store/v1.0.0"}],"href":"/BharatMLStack/category/online-feature-store"},{"type":"category","label":"Quick Start","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"v1.0.0","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Quick Start","href":"/BharatMLStack/quick-start/v1.0.0/quick-start","docId":"quick-start/v1.0.0/quick-start","unlisted":false}]}],"href":"/BharatMLStack/category/quick-start"},{"type":"category","label":"Trufflebox UI","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"v1.0.0","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"User Manual","href":"/BharatMLStack/trufflebox-ui/v1.0.0/userguide","docId":"trufflebox-ui/v1.0.0/userguide","unlisted":false}]}],"href":"/BharatMLStack/category/trufflebox-ui"},{"type":"category","label":"SDKs","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Go SDK","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"v1.0.0","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"GRPC Feature client","href":"/BharatMLStack/sdks/go/v1.0.0/feature_client","docId":"sdks/go/v1.0.0/feature_client","unlisted":false}]}],"href":"/BharatMLStack/category/go-sdk"},{"type":"category","label":"Python SDK","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"v1.0.0","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"GRPC Feature client","href":"/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client","docId":"sdks/python/v1.0.0/grpc_feature_client","unlisted":false},{"type":"link","label":"Spark client","href":"/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client","docId":"sdks/python/v1.0.0/spark_feature_push_client","unlisted":false}],"href":"/BharatMLStack/category/v100"}],"href":"/BharatMLStack/category/python-sdk"}],"href":"/BharatMLStack/category/sdks"}]},"docs":{"online-feature-store/v1.0.0/architecture":{"id":"online-feature-store/v1.0.0/architecture","title":"Architecture","description":"The Online Feature Store (OnFS) is part of BharatMLStack, designed to support real-time ML workloads through low-latency feature retrieval and flexible feature ingestion pipelines. It ensures that features generated offline or online are immediately accessible for inference.","sidebar":"tutorialSidebar"},"online-feature-store/v1.0.0/benchmarks":{"id":"online-feature-store/v1.0.0/benchmarks","title":"Benchmarks","description":"Summary","sidebar":"tutorialSidebar"},"online-feature-store/v1.0.0/data-formats":{"id":"online-feature-store/v1.0.0/data-formats","title":"Data Formats","description":"In this section we will go through the data-formats which is at the hear of online-feature-store, it\'s inspired form other storage efficient formats like parquet & arrow, but custom made to deliver in constraint environment. The two key data-formats are:","sidebar":"tutorialSidebar"},"online-feature-store/v1.0.0/functionalities":{"id":"online-feature-store/v1.0.0/functionalities","title":"Key Functionalities","description":"Overview","sidebar":"tutorialSidebar"},"online-feature-store/v1.0.0/release-notes":{"id":"online-feature-store/v1.0.0/release-notes","title":"Release Notes","description":"Version 1.0.0 \ud83d\ude80","sidebar":"tutorialSidebar"},"quick-start/v1.0.0/quick-start":{"id":"quick-start/v1.0.0/quick-start","title":"Quick Start","description":"Discord","sidebar":"tutorialSidebar"},"sdks/go/v1.0.0/feature_client":{"id":"sdks/go/v1.0.0/feature_client","title":"GRPC Feature client","description":"Build Status","sidebar":"tutorialSidebar"},"sdks/python/v1.0.0/grpc_feature_client":{"id":"sdks/python/v1.0.0/grpc_feature_client","title":"GRPC Feature client","description":"PyPI version","sidebar":"tutorialSidebar"},"sdks/python/v1.0.0/spark_feature_push_client":{"id":"sdks/python/v1.0.0/spark_feature_push_client","title":"Spark client","description":"PyPI version","sidebar":"tutorialSidebar"},"trufflebox-ui/v1.0.0/userguide":{"id":"trufflebox-ui/v1.0.0/userguide","title":"User Manual","description":"This guide covers the complete setup and usage of the Online Feature Store system, including the core services (Online Feature Store and Horizon) and the TruffleBox UI for feature management.","sidebar":"tutorialSidebar"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/4137b431.c6fedbd3.js b/docs/assets/js/4137b431.c6fedbd3.js new file mode 100644 index 00000000..548cc0ed --- /dev/null +++ b/docs/assets/js/4137b431.c6fedbd3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6054],{4019:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"category","label":"Online Feature Store","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"v1.0.0","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Architecture","href":"/BharatMLStack/online-feature-store/v1.0.0/architecture","docId":"online-feature-store/v1.0.0/architecture","unlisted":false},{"type":"link","label":"Data Formats","href":"/BharatMLStack/online-feature-store/v1.0.0/data-formats","docId":"online-feature-store/v1.0.0/data-formats","unlisted":false},{"type":"link","label":"Benchmarks","href":"/BharatMLStack/online-feature-store/v1.0.0/benchmarks","docId":"online-feature-store/v1.0.0/benchmarks","unlisted":false},{"type":"link","label":"Key Functionalities","href":"/BharatMLStack/online-feature-store/v1.0.0/functionalities","docId":"online-feature-store/v1.0.0/functionalities","unlisted":false},{"type":"link","label":"Release Notes","href":"/BharatMLStack/online-feature-store/v1.0.0/release-notes","docId":"online-feature-store/v1.0.0/release-notes","unlisted":false}],"href":"/BharatMLStack/online-feature-store/v1.0.0"}],"href":"/BharatMLStack/category/online-feature-store"},{"type":"category","label":"Inferflow","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"v1.0.0","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Architecture","href":"/BharatMLStack/inferflow/v1.0.0/architecture","docId":"inferflow/v1.0.0/architecture","unlisted":false},{"type":"link","label":"Key Functionalities","href":"/BharatMLStack/inferflow/v1.0.0/functionalities","docId":"inferflow/v1.0.0/functionalities","unlisted":false},{"type":"link","label":"Configuration Guide","href":"/BharatMLStack/inferflow/v1.0.0/configuration","docId":"inferflow/v1.0.0/configuration","unlisted":false},{"type":"link","label":"Release Notes","href":"/BharatMLStack/inferflow/v1.0.0/release-notes","docId":"inferflow/v1.0.0/release-notes","unlisted":false}],"href":"/BharatMLStack/inferflow/v1.0.0"}],"href":"/BharatMLStack/category/inferflow"},{"type":"category","label":"Quick Start","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"v1.0.0","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Quick Start","href":"/BharatMLStack/quick-start/v1.0.0/quick-start","docId":"quick-start/v1.0.0/quick-start","unlisted":false}]}],"href":"/BharatMLStack/category/quick-start"},{"type":"category","label":"Trufflebox UI","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"v1.0.0","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"User Manual","href":"/BharatMLStack/trufflebox-ui/v1.0.0/userguide","docId":"trufflebox-ui/v1.0.0/userguide","unlisted":false}]}],"href":"/BharatMLStack/category/trufflebox-ui"},{"type":"category","label":"SDKs","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Go SDK","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"v1.0.0","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"GRPC Feature client","href":"/BharatMLStack/sdks/go/v1.0.0/feature_client","docId":"sdks/go/v1.0.0/feature_client","unlisted":false}]}],"href":"/BharatMLStack/category/go-sdk"},{"type":"category","label":"Python SDK","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"v1.0.0","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"GRPC Feature client","href":"/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client","docId":"sdks/python/v1.0.0/grpc_feature_client","unlisted":false},{"type":"link","label":"Spark client","href":"/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client","docId":"sdks/python/v1.0.0/spark_feature_push_client","unlisted":false}],"href":"/BharatMLStack/category/v100"}],"href":"/BharatMLStack/category/python-sdk"}],"href":"/BharatMLStack/category/sdks"},{"type":"category","label":"Numerix","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"v1.0.0","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Architecture","href":"/BharatMLStack/numerix/v1.0.0/architecture","docId":"numerix/v1.0.0/architecture","unlisted":false},{"type":"link","label":"Benchmarks","href":"/BharatMLStack/numerix/v1.0.0/benchmarks","docId":"numerix/v1.0.0/benchmarks","unlisted":false},{"type":"link","label":"Key Functionalities","href":"/BharatMLStack/numerix/v1.0.0/functionalities","docId":"numerix/v1.0.0/functionalities","unlisted":false},{"type":"link","label":"Release Notes","href":"/BharatMLStack/numerix/v1.0.0/release-notes","docId":"numerix/v1.0.0/release-notes","unlisted":false}],"href":"/BharatMLStack/numerix/v1.0.0"}],"href":"/BharatMLStack/category/numerix"}]},"docs":{"inferflow/v1.0.0/architecture":{"id":"inferflow/v1.0.0/architecture","title":"Architecture","description":"Inferflow is part of BharatMLStack, a graph-driven feature retrieval and model inference orchestration engine built in Go. It eliminates the need for custom feature retrieval code by using configurable DAG topologies to dynamically resolve entity relationships, fetch features from the Online Feature Store, and orchestrate model scoring \u2014 all driven by configuration stored in etcd.","sidebar":"tutorialSidebar"},"inferflow/v1.0.0/configuration":{"id":"inferflow/v1.0.0/configuration","title":"Configuration Guide","description":"Inferflow is fully config-driven. All model onboarding, feature retrieval logic, DAG topology, and inference behavior are controlled through configuration stored in etcd \u2014 with zero code changes required.","sidebar":"tutorialSidebar"},"inferflow/v1.0.0/functionalities":{"id":"inferflow/v1.0.0/functionalities","title":"Key Functionalities","description":"Overview","sidebar":"tutorialSidebar"},"inferflow/v1.0.0/release-notes":{"id":"inferflow/v1.0.0/release-notes","title":"Release Notes","description":"Version 1.0.0","sidebar":"tutorialSidebar"},"numerix/v1.0.0/architecture":{"id":"numerix/v1.0.0/architecture","title":"Architecture","description":"---","sidebar":"tutorialSidebar"},"numerix/v1.0.0/benchmarks":{"id":"numerix/v1.0.0/benchmarks","title":"Benchmarks","description":"This PoC measures the performance of vector addition in Rust with and without compiler SIMD optimizations. Requests consist of repeated fixed-size vector addition operations processed in parallel by the CPU. These results provide perspective on how much faster SIMD makes vectorized computations, and similar improvements are expected for other vectorized operations in Numerix.","sidebar":"tutorialSidebar"},"numerix/v1.0.0/functionalities":{"id":"numerix/v1.0.0/functionalities","title":"Key Functionalities","description":"Overview","sidebar":"tutorialSidebar"},"numerix/v1.0.0/release-notes":{"id":"numerix/v1.0.0/release-notes","title":"Release Notes","description":"Version 1.0.0 \ud83d\ude80","sidebar":"tutorialSidebar"},"online-feature-store/v1.0.0/architecture":{"id":"online-feature-store/v1.0.0/architecture","title":"Architecture","description":"The Online Feature Store (OnFS) is part of BharatMLStack, designed to support real-time ML workloads through low-latency feature retrieval and flexible feature ingestion pipelines. It ensures that features generated offline or online are immediately accessible for inference.","sidebar":"tutorialSidebar"},"online-feature-store/v1.0.0/benchmarks":{"id":"online-feature-store/v1.0.0/benchmarks","title":"Benchmarks","description":"Summary","sidebar":"tutorialSidebar"},"online-feature-store/v1.0.0/data-formats":{"id":"online-feature-store/v1.0.0/data-formats","title":"Data Formats","description":"In this section we will go through the data-formats which is at the hear of online-feature-store, it\'s inspired form other storage efficient formats like parquet & arrow, but custom made to deliver in constraint environment. The two key data-formats are:","sidebar":"tutorialSidebar"},"online-feature-store/v1.0.0/functionalities":{"id":"online-feature-store/v1.0.0/functionalities","title":"Key Functionalities","description":"Overview","sidebar":"tutorialSidebar"},"online-feature-store/v1.0.0/release-notes":{"id":"online-feature-store/v1.0.0/release-notes","title":"Release Notes","description":"Version 1.0.0 \ud83d\ude80","sidebar":"tutorialSidebar"},"quick-start/v1.0.0/quick-start":{"id":"quick-start/v1.0.0/quick-start","title":"Quick Start","description":"Discord","sidebar":"tutorialSidebar"},"sdks/go/v1.0.0/feature_client":{"id":"sdks/go/v1.0.0/feature_client","title":"GRPC Feature client","description":"Build Status","sidebar":"tutorialSidebar"},"sdks/python/v1.0.0/grpc_feature_client":{"id":"sdks/python/v1.0.0/grpc_feature_client","title":"GRPC Feature client","description":"PyPI version","sidebar":"tutorialSidebar"},"sdks/python/v1.0.0/spark_feature_push_client":{"id":"sdks/python/v1.0.0/spark_feature_push_client","title":"Spark client","description":"PyPI version","sidebar":"tutorialSidebar"},"trufflebox-ui/v1.0.0/userguide":{"id":"trufflebox-ui/v1.0.0/userguide","title":"User Manual","description":"This guide covers the complete setup and usage of the Online Feature Store system, including the core services (Online Feature Store and Horizon) and the TruffleBox UI for feature management.","sidebar":"tutorialSidebar"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/428aafcc.2c1db158.js b/docs/assets/js/428aafcc.2c1db158.js new file mode 100644 index 00000000..813dbcdf --- /dev/null +++ b/docs/assets/js/428aafcc.2c1db158.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5503],{702:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/vss-c482f6eac4c68b3219e4c562a6b717ec.png"},788:e=>{e.exports=JSON.parse('{"permalink":"/BharatMLStack/blog/post-three","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-three/index.md","source":"@site/blog/bharatmlstack-history/post-three/index.md","title":"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search","description":"BharatMLStack","date":"2024-05-21T00:00:00.000Z","tags":[{"inline":true,"label":"model-inference","permalink":"/BharatMLStack/blog/tags/model-inference"},{"inline":true,"label":"embedding-search","permalink":"/BharatMLStack/blog/tags/embedding-search"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"},{"inline":true,"label":"bharatmlstack","permalink":"/BharatMLStack/blog/tags/bharatmlstack"}],"readingTime":3.6,"hasTruncateMarker":false,"authors":[{"name":"Aditya Kumar","title":"Lead Software Engineer @ Meesho","url":"https://github.com/Adit2607","imageURL":"https://github.com/Adit2607.png","key":"aditya","page":null},{"name":"Jaya Kumar","title":"Lead ML Engineer @ Meesho","url":"https://github.com/jayakommuru","imageURL":"https://github.com/jayakommuru.png","key":"jaya","page":null},{"name":"Adarsha Das","title":"Senior Architect @ Meesho","url":"https://github.com/a0d00kc","imageURL":"https://github.com/a0d00kc.png","key":"adarsha","page":null}],"frontMatter":{"slug":"post-three","title":"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search","authors":["aditya","jaya","adarsha"],"date":"2024-05-21T00:00:00.000Z","tags":["model-inference","embedding-search","mlplatform","meesho","bharatmlstack"]},"unlisted":false,"prevItem":{"title":"Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving","permalink":"/BharatMLStack/blog/post-three"},"nextItem":{"title":"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)","permalink":"/BharatMLStack/blog/post-two"}}')},6e3:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/bms-7399e8796d2cd24617c432518ce3f312.png"},7999:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>d});var i=t(788),a=t(4848),r=t(8453);const s={slug:"post-three",title:"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search",authors:["aditya","jaya","adarsha"],date:new Date("2024-05-21T00:00:00.000Z"),tags:["model-inference","embedding-search","mlplatform","meesho","bharatmlstack"]},l=void 0,o={authorsImageUrls:[void 0,void 0,void 0]},d=[{value:"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search",id:"cracking-the-code-scaling-model-inference--real-time-embedding-search",level:2},{value:"Breaking Free from the Scalability Ceiling",id:"breaking-free-from-the-scalability-ceiling",level:2},{value:"The Model Serving Bottleneck\u2014A Wake-Up Call",id:"the-model-serving-bottlenecka-wake-up-call",level:3},{value:"Scaling Triton on GKE",id:"scaling-triton-on-gke",level:3},{value:"Fixing the Cold Start Problem",id:"fixing-the-cold-start-problem",level:3},{value:"Embedding Search: The Last Piece of the Puzzle",id:"embedding-search-the-last-piece-of-the-puzzle",level:2},{value:"Choosing the Right Vector Database",id:"choosing-the-right-vector-database",level:3},{value:"Embedding Freshness & Real-Time Updates",id:"embedding-freshness--real-time-updates",level:3},{value:"Final Takeaways: Scaling Smartly for Real-Time ML",id:"final-takeaways-scaling-smartly-for-real-time-ml",level:2}];function c(e){const n={h2:"h2",h3:"h3",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"BharatMLStack",src:t(6e3).A+"",width:"1396",height:"460"})}),"\n",(0,a.jsx)(n.h2,{id:"cracking-the-code-scaling-model-inference--real-time-embedding-search",children:"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search"}),"\n",(0,a.jsx)(n.p,{children:"By mid-2023, we had transformed our ML stack\u2014building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\ud83d\udd39 Scaling model inference without hitting infrastructure roadblocks"}),"\n",(0,a.jsx)(n.li,{children:"\ud83d\udd39 Moving embedding search from batch to real-time for candidate generation"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Here\u2019s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system."}),"\n",(0,a.jsx)(n.h2,{id:"breaking-free-from-the-scalability-ceiling",children:"Breaking Free from the Scalability Ceiling"}),"\n",(0,a.jsx)(n.h3,{id:"the-model-serving-bottlenecka-wake-up-call",children:"The Model Serving Bottleneck\u2014A Wake-Up Call"}),"\n",(0,a.jsx)(n.p,{children:"July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue\u2014scaling our model-serving infrastructure was taking 10\u201315 minutes. In real-time ML, that\u2019s an eternity.\nIn one of our war rooms, we ran a quick experiment:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\ud83d\ude80 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine."}),"\n",(0,a.jsx)(n.li,{children:"\ud83d\ude80 Fired requests and compared the outputs with our existing cloud-hosted setup."}),"\n",(0,a.jsx)(n.li,{children:"\ud83d\ude80 The results matched\u2014perfectly."}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:'That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn\'t allocate enough compute resources in time. Luckily, they did\u2014but the seed was planted.\nThen in October, just two weeks before MBS, we got an alarming response from our infrastructure team:\n"Node availability may be an issue."\nWith no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?'}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\u2705 p99 latency dropped from 90\u2013100ms to 30\u201340ms"}),"\n",(0,a.jsx)(n.li,{children:"\u2705 Triton handled significantly higher throughput on fewer resources"}),"\n",(0,a.jsx)(n.li,{children:"\u2705 No model changes were needed"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"MBS ran without a hitch, proving that self-hosted inference was the way forward."}),"\n",(0,a.jsx)(n.h3,{id:"scaling-triton-on-gke",children:"Scaling Triton on GKE"}),"\n",(0,a.jsx)(n.p,{children:"This left us with two choices:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"1\ufe0f\u20e3 Port models to a managed cloud inference service, investing time in learning a new deployment stack"}),"\n",(0,a.jsx)(n.li,{children:"2\ufe0f\u20e3 Scale our existing Triton setup on GKE, optimizing for cost and performance"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"We went with Option 2\u2014and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations."}),"\n",(0,a.jsx)(n.h3,{id:"fixing-the-cold-start-problem",children:"Fixing the Cold Start Problem"}),"\n",(0,a.jsx)(n.p,{children:"As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7\u20139 minutes to spin up."}),"\n",(0,a.jsx)(n.p,{children:"After profiling, we found the culprits:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Triton\u2019s base image\u2014a massive 5GB"}),"\n",(0,a.jsx)(n.li,{children:"Model binaries\u2014often 1GB+"}),"\n",(0,a.jsx)(n.li,{children:"Startup delay\u2014mostly due to downloading and initializing these assets"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother."}),"\n",(0,a.jsx)(n.h2,{id:"embedding-search-the-last-piece-of-the-puzzle",children:"Embedding Search: The Last Piece of the Puzzle"}),"\n",(0,a.jsx)(n.p,{children:"By mid-2023, most of our ML stack had gone real-time\u2014except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system."}),"\n",(0,a.jsx)(n.h3,{id:"choosing-the-right-vector-database",children:"Choosing the Right Vector Database"}),"\n",(0,a.jsx)(n.p,{children:"We benchmarked three production-ready vector DBs across key parameters:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Milvus"}),"\n",(0,a.jsx)(n.li,{children:"Qdrant"}),"\n",(0,a.jsx)(n.li,{children:"Weaviate"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"After extensive POCs, Qdrant stood out for its:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\u2705 Blazing-fast search latency on high-dimensional vectors"}),"\n",(0,a.jsx)(n.li,{children:"\u2705 Efficient memory usage, crucial for in-memory workloads"}),"\n",(0,a.jsx)(n.li,{children:"\u2705 Support for upserts and soft deletes, vital for Ads use cases"}),"\n",(0,a.jsx)(n.li,{children:"\u2705 gRPC + REST APIs, making integration seamless"}),"\n",(0,a.jsx)(n.li,{children:"\u2705 Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search\u2014a perfect fit for our needs."}),"\n",(0,a.jsx)(n.h3,{id:"embedding-freshness--real-time-updates",children:"Embedding Freshness & Real-Time Updates"}),"\n",(0,a.jsx)(n.p,{children:"To ensure embeddings stayed up to date, we built a dual ingestion pipeline:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\ud83d\udccc Daily Refresh: A bulk pipeline updated embeddings overnight"}),"\n",(0,a.jsx)(n.li,{children:"\ud83d\udccc Real-Time Updates: Ads events triggered immediate upserts/deletes"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:'This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.'}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"Skye",src:t(702).A+"",width:"1260",height:"644"})}),"\n",(0,a.jsx)(n.h2,{id:"final-takeaways-scaling-smartly-for-real-time-ml",children:"Final Takeaways: Scaling Smartly for Real-Time ML"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\ud83d\ude80 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services"}),"\n",(0,a.jsx)(n.li,{children:"\ud83d\ude80 Building a custom Triton image reduced cold starts, improving responsiveness"}),"\n",(0,a.jsx)(n.li,{children:"\ud83d\ude80 Qdrant-based embedding search enabled real-time personalization at scale"}),"\n",(0,a.jsx)(n.li,{children:"\ud83d\ude80 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"By early 2024, Meesho\u2019s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>l});var i=t(6540);const a={},r=i.createContext(a);function s(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/45a03d07.6212d749.js b/docs/assets/js/45a03d07.6212d749.js new file mode 100644 index 00000000..9dbe9ea8 --- /dev/null +++ b/docs/assets/js/45a03d07.6212d749.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9955],{8539:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"v1.0.0","description":"Numerix v1.0.0","slug":"/inferflow/v1.0.0","permalink":"/BharatMLStack/inferflow/v1.0.0","sidebar":"tutorialSidebar","navigation":{"previous":{"title":"Inferflow","permalink":"/BharatMLStack/category/inferflow"},"next":{"title":"Architecture","permalink":"/BharatMLStack/inferflow/v1.0.0/architecture"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/479eb034.0c88dc68.js b/docs/assets/js/479eb034.fc01692f.js similarity index 70% rename from docs/assets/js/479eb034.0c88dc68.js rename to docs/assets/js/479eb034.fc01692f.js index 560af3f1..7a5850f1 100644 --- a/docs/assets/js/479eb034.0c88dc68.js +++ b/docs/assets/js/479eb034.fc01692f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5425],{9341:a=>{a.exports=JSON.parse('{"tag":{"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform","allTagsPath":"/BharatMLStack/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/BharatMLStack/blog/tags/mlplatform","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5425],{9341:a=>{a.exports=JSON.parse('{"tag":{"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform","allTagsPath":"/BharatMLStack/blog/tags","count":5,"unlisted":false},"listMetadata":{"permalink":"/BharatMLStack/blog/tags/mlplatform","page":1,"postsPerPage":10,"totalPages":1,"totalCount":5,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/4af50aac.a113ce2d.js b/docs/assets/js/4af50aac.f9b29cbf.js similarity index 97% rename from docs/assets/js/4af50aac.a113ce2d.js rename to docs/assets/js/4af50aac.f9b29cbf.js index a6058d52..03afe77a 100644 --- a/docs/assets/js/4af50aac.a113ce2d.js +++ b/docs/assets/js/4af50aac.f9b29cbf.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1964],{6220:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"sdks/go/v1.0.0/feature_client","title":"GRPC Feature client","description":"Build Status","source":"@site/docs/sdks/go/v1.0.0/feature_client.md","sourceDirName":"sdks/go/v1.0.0","slug":"/sdks/go/v1.0.0/feature_client","permalink":"/BharatMLStack/sdks/go/v1.0.0/feature_client","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/sdks/go/v1.0.0/feature_client.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"GRPC Feature client","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"Go SDK","permalink":"/BharatMLStack/category/go-sdk"},"next":{"title":"Python SDK","permalink":"/BharatMLStack/category/python-sdk"}}');var i=t(4848),r=t(8453);const l={title:"GRPC Feature client",sidebar_position:1},o="BharatMLStack Go SDK",a={},c=[{value:"Features",id:"features",level:2},{value:"Installation",id:"installation",level:2},{value:"Configuration",id:"configuration",level:2},{value:"Usage",id:"usage",level:2},{value:"Basic Usage",id:"basic-usage",level:3},{value:"Complete Example",id:"complete-example",level:3},{value:"Development",id:"development",level:2},{value:"Prerequisites",id:"prerequisites",level:3},{value:"Building",id:"building",level:3},{value:"Testing",id:"testing",level:3},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.img,{src:"https://github.com/Meesho/BharatMLStack/actions/workflows/go-sdk.yml/badge.svg",alt:"Build Status"}),"\n",(0,i.jsx)(n.img,{src:"https://img.shields.io/badge/release-v1.0.0-blue?style=flat",alt:"Static Badge"}),"\n",(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:(0,i.jsx)(n.img,{src:"https://img.shields.io/badge/Discord-Join%20Chat-7289da?style=flat&logo=discord&logoColor=white",alt:"Discord"})})]}),"\n",(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"bharatmlstack-go-sdk",children:"BharatMLStack Go SDK"})}),"\n",(0,i.jsx)(n.p,{children:"A Go SDK for interacting with BharatMLStack components, providing easy-to-use client libraries for the Online Feature Store and other services."}),"\n",(0,i.jsx)(n.h2,{id:"features",children:"Features"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Online Feature Store Client"}),": Complete gRPC client for feature retrieval and persistence"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Multiple API Methods"}),": Support for ",(0,i.jsx)(n.code,{children:"RetrieveFeatures"}),", ",(0,i.jsx)(n.code,{children:"RetrieveDecodedFeatures"}),", and ",(0,i.jsx)(n.code,{children:"PersistFeatures"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Protocol Buffer Support"}),": Generated clients from proto definitions with full type safety"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Batch Processing"}),": Configurable batch sizes for efficient bulk operations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Authentication"}),": Built-in support for caller ID and token-based authentication"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Connection Management"}),": Configurable timeouts, TLS, and connection pooling"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Metrics Integration"}),": Built-in timing and count metrics for monitoring"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Type-Safe API"}),": Strongly typed Go interfaces and data structures"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Test Coverage"}),": Comprehensive test suite with mocking support"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"go get github.com/Meesho/BharatMLStack/go-sdk\n"})}),"\n",(0,i.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,i.jsx)(n.p,{children:"The SDK requires a configuration object with the following fields:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Field"}),(0,i.jsx)(n.th,{children:"Type"}),(0,i.jsx)(n.th,{children:"Required"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Host"})}),(0,i.jsx)(n.td,{children:"string"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:'Server hostname (e.g., "localhost", "feature-store.example.com")'})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Port"})}),(0,i.jsx)(n.td,{children:"string"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:'Server port (e.g., "8080", "443")'})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"CallerId"})}),(0,i.jsx)(n.td,{children:"string"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"Unique identifier for your service/application"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"CallerToken"})}),(0,i.jsx)(n.td,{children:"string"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"Authentication token for API access"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"DeadLine"})}),(0,i.jsx)(n.td,{children:"int"}),(0,i.jsx)(n.td,{children:"No"}),(0,i.jsx)(n.td,{children:"Request timeout in milliseconds (default: 5000)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"PlainText"})}),(0,i.jsx)(n.td,{children:"bool"}),(0,i.jsx)(n.td,{children:"No"}),(0,i.jsx)(n.td,{children:"Use plaintext connection instead of TLS (default: false)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BatchSize"})}),(0,i.jsx)(n.td,{children:"int"}),(0,i.jsx)(n.td,{children:"No"}),(0,i.jsx)(n.td,{children:"Maximum batch size for bulk operations (default: 50)"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,i.jsx)(n.h3,{id:"basic-usage",children:"Basic Usage"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "log"\n \n "github.com/Meesho/BharatMLStack/go-sdk/pkg/onfs"\n)\n\nfunc main() {\n config := &onfs.Config{\n Host: "localhost",\n Port: "8080",\n PlainText: true, // For local development\n CallerId: "my-service",\n CallerToken: "my-token",\n }\n\n // Initialize client (timing and count can be nil)\n client := onfs.NewClientV1(config, nil, nil)\n \n // Your feature operations here...\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"complete-example",children:"Complete Example"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "log"\n "time"\n \n "github.com/Meesho/BharatMLStack/go-sdk/pkg/onfs"\n)\n\nfunc main() {\n // Create configuration\n config := &onfs.Config{\n Host: "localhost",\n Port: "8080",\n DeadLine: 5000, // 5 seconds timeout in milliseconds\n PlainText: true, // Use plaintext connection for local development\n BatchSize: 50, // Optional: batch size for requests\n CallerId: "your-service-id",\n CallerToken: "your-auth-token",\n }\n\n // Timing and count functions (can be nil for basic usage)\n timing := func(name string, value time.Duration, tags []string) {\n log.Printf("Timing: %s took %v with tags %v", name, value, tags)\n }\n count := func(name string, value int64, tags []string) {\n log.Printf("Count: %s = %d with tags %v", name, value, tags)\n }\n\n // Initialize the client\n client := onfs.InitClient(onfs.Version1, config, timing, count)\n // Or alternatively use: client := onfs.NewClientV1(config, timing, count)\n\n ctx := context.Background()\n\n // Example: Retrieve features\n query := &onfs.Query{\n EntityLabel: "user",\n FeatureGroups: []onfs.FeatureGroup{\n {\n Label: "user_features",\n FeatureLabels: []string{"age", "location", "preferences"},\n },\n },\n KeysSchema: []string{"user_id"},\n Keys: []onfs.Keys{\n {Cols: []string{"12345"}},\n {Cols: []string{"67890"}},\n },\n }\n\n result, err := client.RetrieveFeatures(ctx, query)\n if err != nil {\n log.Fatalf("Failed to retrieve features: %v", err)\n }\n\n log.Printf("Retrieved %d rows for entity %s", len(result.Rows), result.EntityLabel)\n\n // Example: Retrieve decoded features (string values)\n decodedResult, err := client.RetrieveDecodedFeatures(ctx, query)\n if err != nil {\n log.Fatalf("Failed to retrieve decoded features: %v", err)\n }\n\n log.Printf("Retrieved %d decoded rows", len(decodedResult.Rows))\n\n // Example: Persist features\n persistRequest := &onfs.PersistFeaturesRequest{\n EntityLabel: "user",\n KeysSchema: []string{"user_id"},\n FeatureGroups: []onfs.FeatureGroupSchema{\n {\n Label: "user_features",\n FeatureLabels: []string{"age", "location"},\n },\n },\n Data: []onfs.Data{\n {\n KeyValues: []string{"12345"},\n FeatureValues: []onfs.FeatureValues{\n {\n Values: onfs.Values{\n Int32Values: []int32{25},\n StringValues: []string{"New York"},\n },\n },\n },\n },\n },\n }\n\n persistResponse, err := client.PersistFeatures(ctx, persistRequest)\n if err != nil {\n log.Fatalf("Failed to persist features: %v", err)\n }\n\n log.Printf("Persist result: %s", persistResponse.Message)\n}\n'})}),"\n",(0,i.jsx)(n.h2,{id:"development",children:"Development"}),"\n",(0,i.jsx)(n.h3,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Go 1.22 or later (as specified in go.mod)"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"building",children:"Building"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Build all packages\ngo build ./...\n\n# Run tests\ngo test ./...\n\n# Run tests with coverage\ngo test -v -coverprofile=coverage.out ./...\ngo tool cover -html=coverage.out\n"})}),"\n",(0,i.jsx)(n.h3,{id:"testing",children:"Testing"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Run all tests\ngo test -v ./...\n\n# Run specific package tests\ngo test -v ./pkg/onfs\n\n# Run with race detection\ngo test -race ./...\n"})}),"\n",(0,i.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,i.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,i.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\ud83d\udcac ",(0,i.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,i.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,i.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,i.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,i.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>l,x:()=>o});var s=t(6540);const i={},r=s.createContext(i);function l(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1964],{6220:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"sdks/go/v1.0.0/feature_client","title":"GRPC Feature client","description":"Build Status","source":"@site/docs/sdks/go/v1.0.0/feature_client.md","sourceDirName":"sdks/go/v1.0.0","slug":"/sdks/go/v1.0.0/feature_client","permalink":"/BharatMLStack/sdks/go/v1.0.0/feature_client","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/sdks/go/v1.0.0/feature_client.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"GRPC Feature client","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"Go SDK","permalink":"/BharatMLStack/category/go-sdk"},"next":{"title":"Python SDK","permalink":"/BharatMLStack/category/python-sdk"}}');var i=t(4848),r=t(8453);const l={title:"GRPC Feature client",sidebar_position:1},o="BharatMLStack Go SDK",a={},c=[{value:"Features",id:"features",level:2},{value:"Installation",id:"installation",level:2},{value:"Configuration",id:"configuration",level:2},{value:"Usage",id:"usage",level:2},{value:"Basic Usage",id:"basic-usage",level:3},{value:"Complete Example",id:"complete-example",level:3},{value:"Development",id:"development",level:2},{value:"Prerequisites",id:"prerequisites",level:3},{value:"Building",id:"building",level:3},{value:"Testing",id:"testing",level:3},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.img,{src:"https://github.com/Meesho/BharatMLStack/actions/workflows/go-sdk.yml/badge.svg",alt:"Build Status"}),"\n",(0,i.jsx)(n.img,{src:"https://img.shields.io/badge/release-v1.0.0-blue?style=flat",alt:"Static Badge"}),"\n",(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:(0,i.jsx)(n.img,{src:"https://img.shields.io/badge/Discord-Join%20Chat-7289da?style=flat&logo=discord&logoColor=white",alt:"Discord"})})]}),"\n",(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"bharatmlstack-go-sdk",children:"BharatMLStack Go SDK"})}),"\n",(0,i.jsx)(n.p,{children:"A Go SDK for interacting with BharatMLStack components, providing easy-to-use client libraries for the Online Feature Store and other services."}),"\n",(0,i.jsx)(n.h2,{id:"features",children:"Features"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Online Feature Store Client"}),": Complete gRPC client for feature retrieval and persistence"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Multiple API Methods"}),": Support for ",(0,i.jsx)(n.code,{children:"RetrieveFeatures"}),", ",(0,i.jsx)(n.code,{children:"RetrieveDecodedFeatures"}),", and ",(0,i.jsx)(n.code,{children:"PersistFeatures"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Protocol Buffer Support"}),": Generated clients from proto definitions with full type safety"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Batch Processing"}),": Configurable batch sizes for efficient bulk operations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Authentication"}),": Built-in support for caller ID and token-based authentication"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Connection Management"}),": Configurable timeouts, TLS, and connection pooling"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Metrics Integration"}),": Built-in timing and count metrics for monitoring"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Type-Safe API"}),": Strongly typed Go interfaces and data structures"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Test Coverage"}),": Comprehensive test suite with mocking support"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"go get github.com/Meesho/BharatMLStack/go-sdk\n"})}),"\n",(0,i.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,i.jsx)(n.p,{children:"The SDK requires a configuration object with the following fields:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Field"}),(0,i.jsx)(n.th,{children:"Type"}),(0,i.jsx)(n.th,{children:"Required"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Host"})}),(0,i.jsx)(n.td,{children:"string"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:'Server hostname (e.g., "localhost", "feature-store.example.com")'})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Port"})}),(0,i.jsx)(n.td,{children:"string"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:'Server port (e.g., "8080", "443")'})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"CallerId"})}),(0,i.jsx)(n.td,{children:"string"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"Unique identifier for your service/application"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"CallerToken"})}),(0,i.jsx)(n.td,{children:"string"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"Authentication token for API access"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"DeadLine"})}),(0,i.jsx)(n.td,{children:"int"}),(0,i.jsx)(n.td,{children:"No"}),(0,i.jsx)(n.td,{children:"Request timeout in milliseconds (default: 5000)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"PlainText"})}),(0,i.jsx)(n.td,{children:"bool"}),(0,i.jsx)(n.td,{children:"No"}),(0,i.jsx)(n.td,{children:"Use plaintext connection instead of TLS (default: false)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BatchSize"})}),(0,i.jsx)(n.td,{children:"int"}),(0,i.jsx)(n.td,{children:"No"}),(0,i.jsx)(n.td,{children:"Maximum batch size for bulk operations (default: 50)"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,i.jsx)(n.h3,{id:"basic-usage",children:"Basic Usage"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "log"\n \n "github.com/Meesho/BharatMLStack/go-sdk/pkg/onfs"\n)\n\nfunc main() {\n config := &onfs.Config{\n Host: "localhost",\n Port: "8080",\n PlainText: true, // For local development\n CallerId: "my-service",\n CallerToken: "my-token",\n }\n\n // Initialize client (timing and count can be nil)\n client := onfs.NewClientV1(config, nil, nil)\n \n // Your feature operations here...\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"complete-example",children:"Complete Example"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "log"\n "time"\n \n "github.com/Meesho/BharatMLStack/go-sdk/pkg/onfs"\n)\n\nfunc main() {\n // Create configuration\n config := &onfs.Config{\n Host: "localhost",\n Port: "8080",\n DeadLine: 5000, // 5 seconds timeout in milliseconds\n PlainText: true, // Use plaintext connection for local development\n BatchSize: 50, // Optional: batch size for requests\n CallerId: "your-service-id",\n CallerToken: "your-auth-token",\n }\n\n // Timing and count functions (can be nil for basic usage)\n timing := func(name string, value time.Duration, tags []string) {\n log.Printf("Timing: %s took %v with tags %v", name, value, tags)\n }\n count := func(name string, value int64, tags []string) {\n log.Printf("Count: %s = %d with tags %v", name, value, tags)\n }\n\n // Initialize the client\n client := onfs.InitClient(onfs.Version1, config, timing, count)\n // Or alternatively use: client := onfs.NewClientV1(config, timing, count)\n\n ctx := context.Background()\n\n // Example: Retrieve features\n query := &onfs.Query{\n EntityLabel: "user",\n FeatureGroups: []onfs.FeatureGroup{\n {\n Label: "user_features",\n FeatureLabels: []string{"age", "location", "preferences"},\n },\n },\n KeysSchema: []string{"user_id"},\n Keys: []onfs.Keys{\n {Cols: []string{"12345"}},\n {Cols: []string{"67890"}},\n },\n }\n\n result, err := client.RetrieveFeatures(ctx, query)\n if err != nil {\n log.Fatalf("Failed to retrieve features: %v", err)\n }\n\n log.Printf("Retrieved %d rows for entity %s", len(result.Rows), result.EntityLabel)\n\n // Example: Retrieve decoded features (string values)\n decodedResult, err := client.RetrieveDecodedFeatures(ctx, query)\n if err != nil {\n log.Fatalf("Failed to retrieve decoded features: %v", err)\n }\n\n log.Printf("Retrieved %d decoded rows", len(decodedResult.Rows))\n\n // Example: Persist features\n persistRequest := &onfs.PersistFeaturesRequest{\n EntityLabel: "user",\n KeysSchema: []string{"user_id"},\n FeatureGroups: []onfs.FeatureGroupSchema{\n {\n Label: "user_features",\n FeatureLabels: []string{"age", "location"},\n },\n },\n Data: []onfs.Data{\n {\n KeyValues: []string{"12345"},\n FeatureValues: []onfs.FeatureValues{\n {\n Values: onfs.Values{\n Int32Values: []int32{25},\n StringValues: []string{"New York"},\n },\n },\n },\n },\n },\n }\n\n persistResponse, err := client.PersistFeatures(ctx, persistRequest)\n if err != nil {\n log.Fatalf("Failed to persist features: %v", err)\n }\n\n log.Printf("Persist result: %s", persistResponse.Message)\n}\n'})}),"\n",(0,i.jsx)(n.h2,{id:"development",children:"Development"}),"\n",(0,i.jsx)(n.h3,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Go 1.22 or later (as specified in go.mod)"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"building",children:"Building"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Build all packages\ngo build ./...\n\n# Run tests\ngo test ./...\n\n# Run tests with coverage\ngo test -v -coverprofile=coverage.out ./...\ngo tool cover -html=coverage.out\n"})}),"\n",(0,i.jsx)(n.h3,{id:"testing",children:"Testing"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Run all tests\ngo test -v ./...\n\n# Run specific package tests\ngo test -v ./pkg/onfs\n\n# Run with race detection\ngo test -race ./...\n"})}),"\n",(0,i.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,i.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,i.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\ud83d\udcac ",(0,i.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,i.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,i.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,i.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,i.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>l,x:()=>o});var s=t(6540);const i={},r=s.createContext(i);function l(e){const n=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/4caa95bf.2e5bda05.js b/docs/assets/js/4caa95bf.2e5bda05.js deleted file mode 100644 index 910749a2..00000000 --- a/docs/assets/js/4caa95bf.2e5bda05.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2344],{551:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/v1.0.0-csdb-skip-read-e3926080f7341aa7d3c6ec6d8274ea14.png"},1807:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/v1.0.0-psdb-fixed-length-encodding-dd252110b084e01cf38f21de16b3a1a5.png"},2863:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/v1.0.0-psdb-string-encoding-b1d69e9452269124d1b545020fa27d63.png"},5019:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/v1.0.0-psdb-anatomy-c1735559f93dce6d0bb3894d16047059.png"},8453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>l});var t=i(6540);const s={},r=t.createContext(s);function d(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),t.createElement(r.Provider,{value:n},e.children)}},8726:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/v1.0.0-psdb-bool-encoding-4b154fdf5e6d79a67c91b6fb21c7209e.png"},9584:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"online-feature-store/v1.0.0/data-formats","title":"Data Formats","description":"In this section we will go through the data-formats which is at the hear of online-feature-store, it\'s inspired form other storage efficient formats like parquet & arrow, but custom made to deliver in constraint environment. The two key data-formats are:","source":"@site/docs/online-feature-store/v1.0.0/data-formats.md","sourceDirName":"online-feature-store/v1.0.0","slug":"/online-feature-store/v1.0.0/data-formats","permalink":"/BharatMLStack/online-feature-store/v1.0.0/data-formats","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/online-feature-store/v1.0.0/data-formats.md","tags":[],"version":"current","sidebarPosition":2,"frontMatter":{"title":"Data Formats","sidebar_position":2},"sidebar":"tutorialSidebar","previous":{"title":"Architecture","permalink":"/BharatMLStack/online-feature-store/v1.0.0/architecture"},"next":{"title":"Benchmarks","permalink":"/BharatMLStack/online-feature-store/v1.0.0/benchmarks"}}');var s=i(4848),r=i(8453);const d={title:"Data Formats",sidebar_position:2},l="Data Format for Permanent & Cache Storage",c={},a=[{value:"PSDB (Permanent Storage Data Block) Format",id:"psdb-permanent-storage-data-block-format",level:2},{value:"\ud83e\uddf1 Structure Overview",id:"-structure-overview",level:3},{value:"Supported Data Types",id:"supported-data-types",level:3},{value:"Scalar Types",id:"scalar-types",level:4},{value:"Vector Types",id:"vector-types",level:4},{value:"\ud83d\udce6 Encoding for Scalar Feature Type",id:"-encoding-for-scalar-feature-type",level:3},{value:"1. \ud83d\udd21 String Feature Group (Variable Length Encoding using Pascal)",id:"1--string-feature-group-variable-length-encoding-using-pascal",level:4},{value:"2. \ud83d\udfe9 Boolean Feature Group (Bit-Packed)",id:"2--boolean-feature-group-bit-packed",level:4},{value:"3. \ud83d\udccf Fixed-Length Feature Group",id:"3--fixed-length-feature-group",level:4},{value:"4. Compression",id:"4-compression",level:4},{value:"\ud83e\uddec Encoding for Vector Types",id:"-encoding-for-vector-types",level:3},{value:"Conceptual Overview",id:"conceptual-overview",level:4},{value:"Vector Length Metadata",id:"vector-length-metadata",level:4},{value:"Encoding Process",id:"encoding-process",level:4},{value:"Input Structure",id:"input-structure",level:5},{value:"Length Validation",id:"length-validation",level:5},{value:"Flattening Strategy",id:"flattening-strategy",level:5},{value:"Contiguous Layout",id:"contiguous-layout",level:5},{value:"\ud83d\udd04 Deserialization/Decoding Flow",id:"-deserializationdecoding-flow",level:3},{value:"Memory Efficiency Benefits",id:"memory-efficiency-benefits",level:3},{value:"Cache Storage Data Block (CSDB) Design",id:"cache-storage-data-block-csdb-design",level:2},{value:"Overview",id:"overview",level:3},{value:"Structure and Purpose",id:"structure-and-purpose",level:3},{value:"Core Fields and Memory Layout",id:"core-fields-and-memory-layout",level:4},{value:"Cache Types",id:"cache-types",level:4},{value:"Format & Encoding",id:"format--encoding",level:3},{value:"Differences Between In-Memory and Distributed Caching",id:"differences-between-in-memory-and-distributed-caching",level:3},{value:"Optimizations & Features",id:"optimizations--features",level:3}];function o(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"data-format-for-permanent--cache-storage",children:"Data Format for Permanent & Cache Storage"})}),"\n",(0,s.jsx)(n.p,{children:"In this section we will go through the data-formats which is at the hear of online-feature-store, it's inspired form other storage efficient formats like parquet & arrow, but custom made to deliver in constraint environment. The two key data-formats are:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"PSDB"})," - Permanent Storage Data Block used wile storing data in ScyllaDB"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"CSDB"})," - Cache Storage Data Block used while storing data in DragonflyDB or Redis, optimal for KV"]}),"\n",(0,s.jsx)(n.li,{}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"psdb-permanent-storage-data-block-format",children:"PSDB (Permanent Storage Data Block) Format"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"PSDB"})," format is a compact, versioned, and schema-aware binary layout used to store feature groups efficiently for ML inference. It supports multiple datatypes (strings, booleans, fixed-size vectors), versioning, TTL, and metadata encoding in a compact header."]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"-structure-overview",children:"\ud83e\uddf1 Structure Overview"}),"\n",(0,s.jsx)(n.p,{children:"Each PSDB block is composed of multiple byte sections:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Permanent Storage Data Block Anatomy",src:i(5019).A+"",width:"1854",height:"1102"})}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Byte"}),(0,s.jsx)(n.th,{children:"Bits"}),(0,s.jsx)(n.th,{children:"Field"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"0-1"}),(0,s.jsx)(n.td,{children:"0-15"}),(0,s.jsx)(n.td,{children:"Feature Schema Version"}),(0,s.jsx)(n.td,{children:"Version for tracking schema changes (additions/deletions) in feature group"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"2-6"}),(0,s.jsx)(n.td,{children:"16-55"}),(0,s.jsx)(n.td,{children:"Expiry Timestamp"}),(0,s.jsx)(n.td,{children:"Encoded as a compact representation, ~513 days max"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"7"}),(0,s.jsx)(n.td,{children:"56-59"}),(0,s.jsx)(n.td,{children:"Layout Version"}),(0,s.jsx)(n.td,{children:"Used to ensure backward compatibility with layout format changes"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"7"}),(0,s.jsx)(n.td,{children:"60-62"}),(0,s.jsx)(n.td,{children:"Compression Type"}),(0,s.jsx)(n.td,{children:"3-bit field specifying compression algorithm"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"7-8"}),(0,s.jsx)(n.td,{children:"63-67"}),(0,s.jsx)(n.td,{children:"Data Type"}),(0,s.jsx)(n.td,{children:"5-bit field split across bytes 7 and 8"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"8"}),(0,s.jsx)(n.td,{children:"68-71"}),(0,s.jsx)(n.td,{children:"Bool Last Valid Bit"}),(0,s.jsx)(n.td,{children:"4-bit field for last valid boolean bit"})]})]})]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"supported-data-types",children:"Supported Data Types"}),"\n",(0,s.jsx)(n.h4,{id:"scalar-types",children:"Scalar Types"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Container"}),(0,s.jsx)(n.th,{children:"Size"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"FP32"}),", ",(0,s.jsx)(n.code,{children:"FP16"}),", ",(0,s.jsx)(n.code,{children:"FP8E4M3"}),", ",(0,s.jsx)(n.code,{children:"FP8E5M2"})]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]float32"})}),(0,s.jsx)(n.td,{children:"4/2/1/1 bytes"}),(0,s.jsx)(n.td,{children:"Floating point numbers"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"Int32"}),", ",(0,s.jsx)(n.code,{children:"Int16"}),", ",(0,s.jsx)(n.code,{children:"Int8"})]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]int32"})}),(0,s.jsx)(n.td,{children:"4/2/1 bytes"}),(0,s.jsx)(n.td,{children:"Signed integers"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"Uint32"}),", ",(0,s.jsx)(n.code,{children:"Uint16"}),", ",(0,s.jsx)(n.code,{children:"Uint8"})]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]uint32"})}),(0,s.jsx)(n.td,{children:"4/2/1 bytes"}),(0,s.jsx)(n.td,{children:"Unsigned integers"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"FP64"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]float64"})}),(0,s.jsx)(n.td,{children:"8 bytes"}),(0,s.jsx)(n.td,{children:"Double precision float"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Int64"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]int64"})}),(0,s.jsx)(n.td,{children:"8 bytes"}),(0,s.jsx)(n.td,{children:"64-bit signed integer"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Uint64"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]uint64"})}),(0,s.jsx)(n.td,{children:"8 bytes"}),(0,s.jsx)(n.td,{children:"64-bit unsigned integer"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"String"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]string"})}),(0,s.jsx)(n.td,{children:"Variable"}),(0,s.jsx)(n.td,{children:"Pascal-style strings"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Bool"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]uint8"})}),(0,s.jsx)(n.td,{children:"Bit-packed"}),(0,s.jsx)(n.td,{children:"Boolean values"})]})]})]}),"\n",(0,s.jsx)(n.h4,{id:"vector-types",children:"Vector Types"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Container"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"FP32Vector"}),", ",(0,s.jsx)(n.code,{children:"FP16Vector"}),", etc."]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]float32"})}),(0,s.jsx)(n.td,{children:"2D slices of floating point"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"Int32Vector"}),", ",(0,s.jsx)(n.code,{children:"Int16Vector"}),", etc."]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]int32"})}),(0,s.jsx)(n.td,{children:"2D slices of signed integers"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"Uint32Vector"}),", ",(0,s.jsx)(n.code,{children:"Uint16Vector"}),", etc."]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]uint32"})}),(0,s.jsx)(n.td,{children:"2D slices of unsigned integers"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"FP64Vector"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]float64"})}),(0,s.jsx)(n.td,{children:"2D slices of doubles"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Int64Vector"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]int64"})}),(0,s.jsx)(n.td,{children:"2D slices of 64-bit signed"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Uint64Vector"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]uint64"})}),(0,s.jsx)(n.td,{children:"2D slices of 64-bit unsigned"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"StringVector"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]string"})}),(0,s.jsx)(n.td,{children:"2D slices of strings"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"BoolVector"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]uint8"})}),(0,s.jsx)(n.td,{children:"2D slices of bit-packed bools"})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"-encoding-for-scalar-feature-type",children:"\ud83d\udce6 Encoding for Scalar Feature Type"}),"\n",(0,s.jsx)(n.h4,{id:"1--string-feature-group-variable-length-encoding-using-pascal",children:"1. \ud83d\udd21 String Feature Group (Variable Length Encoding using Pascal)"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Max string length: ",(0,s.jsx)(n.strong,{children:"65536"})]}),"\n",(0,s.jsxs)(n.li,{children:["Format:\n",(0,s.jsx)(n.img,{alt:"PSDB String encoding",src:i(2863).A+"",width:"1488",height:"204"})]}),"\n",(0,s.jsxs)(n.li,{children:["Deserialization:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Read length prefixes"}),"\n",(0,s.jsxs)(n.li,{children:["Extract string bytes using ",(0,s.jsx)(n.code,{children:"StrLenX"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"2--boolean-feature-group-bit-packed",children:"2. \ud83d\udfe9 Boolean Feature Group (Bit-Packed)"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Saves space using bit-level packing."}),"\n",(0,s.jsxs)(n.li,{children:["Encoding:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Raw: 1 byte per feature"}),"\n",(0,s.jsx)(n.li,{children:"Bit-packed: 1 bit per boolean"}),"\n",(0,s.jsxs)(n.li,{children:["Additional index (",(0,s.jsx)(n.code,{children:"bool last idx"}),") stores where the last bit resides"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Format:\n",(0,s.jsx)(n.img,{alt:"PSDB Bool encoding",src:i(8726).A+"",width:"1120",height:"712"})]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"3--fixed-length-feature-group",children:"3. \ud83d\udccf Fixed-Length Feature Group"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["For fixed-size vectors (",(0,s.jsx)(n.code,{children:"n"})," bytes each)"]}),"\n",(0,s.jsxs)(n.li,{children:["Format:\n",(0,s.jsx)(n.img,{alt:"PSDB Fixed Length Datatype encoding",src:i(1807).A+"",width:"1122",height:"202"})]}),"\n",(0,s.jsx)(n.li,{children:"Efficient for dense numeric features like float32, int64, etc."}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"4-compression",children:"4. Compression"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"TypeNone (0)"}),": Raw storage"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"TypeZSTD (1)"}),": Compressed using Zstandard"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Compression is opportunistic. During serialization, if compressed size is not smaller, PSDB falls back to uncompressed format. It keeps the read/high througput path use less CPU cycles. Also only data part of PSDB is compressed allowing decompression only if block has a valid TTL"}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"-encoding-for-vector-types",children:"\ud83e\uddec Encoding for Vector Types"}),"\n",(0,s.jsx)(n.h4,{id:"conceptual-overview",children:"Conceptual Overview"}),"\n",(0,s.jsx)(n.p,{children:"PSDB encodes vector data by flattening multi-dimensional arrays into a single contiguous byte buffer while preserving the ability to reconstruct the original vector boundaries."}),"\n",(0,s.jsx)(n.h4,{id:"vector-length-metadata",children:"Vector Length Metadata"}),"\n",(0,s.jsx)(n.p,{children:"Each feature group maintains metadata about vector dimensions in the Feature Registry. For example, if a feature group has:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"fg1:\n version-2:\n features:\n f1: { vector_len: 6, default: [bytes] }\n f2: { vector_len: 3, default: [bytes] }\n version-1:\n features:\n f1: { vector_len: 6, default: [bytes] }\n"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Feature f1 with vector_len: 6"}),"\n",(0,s.jsx)(n.li,{children:"Feature f2 with vector_len: 3"}),"\n",(0,s.jsx)(n.li,{}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This means:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"f1"})," contains vectors of exactly 6 elements each"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"f2"})," contains vectors of exactly 3 elements each"]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"encoding-process",children:"Encoding Process"}),"\n",(0,s.jsx)(n.h5,{id:"input-structure",children:(0,s.jsx)(n.strong,{children:"Input Structure"})}),"\n",(0,s.jsx)(n.p,{children:"The serializer receives vector data as 2D slices where:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Outer dimension represents different feature instances/entities"}),"\n",(0,s.jsx)(n.li,{children:"Inner dimension represents the vector elements for each instance"}),"\n"]}),"\n",(0,s.jsx)(n.h5,{id:"length-validation",children:(0,s.jsx)(n.strong,{children:"Length Validation"})}),"\n",(0,s.jsx)(n.p,{children:"Before encoding, PSDB validates that each vector's actual length matches the declared vector_len from the feature metadata. This ensures data integrity and enables efficient decoding."}),"\n",(0,s.jsx)(n.h5,{id:"flattening-strategy",children:(0,s.jsx)(n.strong,{children:"Flattening Strategy"})}),"\n",(0,s.jsx)(n.p,{children:"Vectors are serialized in row-major order (also called C-style order):"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"All elements of the first vector are written consecutively"}),"\n",(0,s.jsx)(n.li,{children:"Followed by all elements of the second vector"}),"\n",(0,s.jsx)(n.li,{children:"And so on..."}),"\n"]}),"\n",(0,s.jsx)(n.h5,{id:"contiguous-layout",children:(0,s.jsx)(n.strong,{children:"Contiguous Layout"})}),"\n",(0,s.jsx)(n.p,{children:"The resulting byte buffer contains all vector elements placed end-to-end without gaps or separators. The decoder can reconstruct vector boundaries because it knows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The data type size (e.g., 4 bytes for float32), from feature registry"}),"\n",(0,s.jsx)(n.li,{children:"The vector length for each position, from feature registry"}),"\n",(0,s.jsx)(n.li,{children:"The total number of vectors, from feature registry"}),"\n",(0,s.jsxs)(n.li,{children:["In case of ",(0,s.jsx)(n.code,{children:"variable length"})," length is encoded into the data, like for ",(0,s.jsx)(n.code,{children:"String"})," data-type"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"-deserializationdecoding-flow",children:"\ud83d\udd04 Deserialization/Decoding Flow"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Extract version"})," from first 2 bytes."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Look up schema"})," from etcd using the version."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Determine feature shapes"})," (e.g., vector lengths)."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Slice and decode"})," data from byte buffer accordingly."]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"memory-efficiency-benefits",children:"Memory Efficiency Benefits"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"No Padding"}),": Elements are packed tightly without alignment padding"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"No Delimiters"}),": Vector boundaries are implicit, not stored explicitly"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Cache Friendly"}),": Sequential memory access patterns during encoding/decoding"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Minimal Metadata"}),": Only vector lengths are stored separately, not per-element"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"cache-storage-data-block-csdb-design",children:"Cache Storage Data Block (CSDB) Design"}),"\n",(0,s.jsx)(n.h3,{id:"overview",children:"Overview"}),"\n",(0,s.jsx)(n.p,{children:"The Cache Storage Data Block (CSDB) is a compact binary data format that encapsulates serialized data blocks for multiple feature groups. It is designed to support both in-memory and distributed caching of deserialized PSDB (Permanent Storage Data Block) content, optimizing for speed, deduplication, and minimal memory overhead."}),"\n",(0,s.jsx)(n.h3,{id:"structure-and-purpose",children:"Structure and Purpose"}),"\n",(0,s.jsx)(n.p,{children:"Each CSDB contains a mapping of feature group IDs (FG IDs) to deserialized PSDBs. For distributed systems, this structure is flattened into a serialized byte slice. The CSDB supports layout versioning for backward compatibility and negative caching for feature groups with no associated data."}),"\n",(0,s.jsx)(n.h4,{id:"core-fields-and-memory-layout",children:"Core Fields and Memory Layout"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:"type CacheStorageDataBlock struct {\n // 8-byte aligned map pointer\n FGIdToDDB map[int]*DeserializedPSDB // offset: 0\n\n // 24-byte slice (ptr, len, cap)\n serializedCSDB []byte // offset: 8\n\n // 4-byte fields\n TTL uint32 // offset: 32\n\n // 1-byte fields\n layoutVersion uint8 // offset: 36\n cacheType CacheType // offset: 37\n // 2 bytes padding to maintain 4-byte alignment\n}\n"})}),"\n",(0,s.jsx)(n.p,{children:"The structure is memory-aligned for optimal performance:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Pointers and slices are 8-byte aligned"}),"\n",(0,s.jsxs)(n.li,{children:["Smaller fields (like ",(0,s.jsx)(n.code,{children:"uint8"}),") are grouped and padded to avoid false sharing"]}),"\n",(0,s.jsx)(n.li,{children:"This layout ensures efficient use of CPU caches during access"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"cache-types",children:"Cache Types"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"In-Memory Cache"}),": Uses the ",(0,s.jsx)(n.code,{children:"FGIdToDDB"})," map directly and avoids serialization unless explicitly requested."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Distributed Cache"}),": Stores a serialized binary format in ",(0,s.jsx)(n.code,{children:"serializedCSDB"}),", which is deserialized lazily when required."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"format--encoding",children:"Format & Encoding"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"CSDB Binary Layout"}),": Serialized CSDBs follow this compact format:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"[LayoutVersion (1 byte)][FGID (2 bytes)][DataLen (2 bytes)][Data ...] \u2192 repeated per feature group\n"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["FGID and DataLen are encoded as ",(0,s.jsx)(n.code,{children:"uint16"})]}),"\n",(0,s.jsxs)(n.li,{children:["If ",(0,s.jsx)(n.code,{children:"DataLen == 0"}),", it denotes a negative cache (no data available for that FG)"]}),"\n",(0,s.jsx)(n.li,{children:"The data section contains the PSDB header and either compressed or uncompressed data"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This layout allows fast scanning and partial deserialization for selected FG IDs, making it optimal for large-scale caching systems."}),"\n",(0,s.jsx)(n.h3,{id:"differences-between-in-memory-and-distributed-caching",children:"Differences Between In-Memory and Distributed Caching"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Aspect"}),(0,s.jsx)(n.th,{children:"In-Memory CSDB"}),(0,s.jsx)(n.th,{children:"Distributed CSDB"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Storage Format"}),(0,s.jsx)(n.td,{children:"Live Go objects (map[int]*DeserializedPSDB)"}),(0,s.jsxs)(n.td,{children:["Serialized byte buffer (",(0,s.jsx)(n.code,{children:"[]byte"}),")"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Deserialization"}),(0,s.jsx)(n.td,{children:"Performed on-demand using offset map"}),(0,s.jsx)(n.td,{children:"Performed on-demand using offset map"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Compression"}),(0,s.jsx)(n.td,{children:"Optional during serialization"}),(0,s.jsx)(n.td,{children:"Typically enabled to reduce payload size"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Usage Pattern"}),(0,s.jsx)(n.td,{children:"Fast lookup in active process memory"}),(0,s.jsx)(n.td,{children:"Cross-node cache sharing and persistence"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Memory Overhead"}),(0,s.jsx)(n.td,{children:"Higher (due to live objects)"}),(0,s.jsx)(n.td,{children:"Lower (compact representation)"})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"optimizations--features",children:"Optimizations & Features"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Partial FG ID Fetch"}),": When only a subset of FG IDs is needed, CSDB avoids unnecessary deserialization of other IDs."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Negative Caching"}),": FG IDs with no data are encoded with ",(0,s.jsx)(n.code,{children:"DataLen=0"}),", saving space and avoiding repeated lookups."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Offset-Length Map"}),": During deserialization, FGID to offset+length pairs are cached internally for efficient random access."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Versioning Support"}),": Layout version is stored as the first byte to enable format upgrades while maintaining backward compatibility."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Diagram below explains how compute cycles are saved by partial de-compression."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"CSDB Partial Decompression",src:i(551).A+"",width:"2292",height:"828"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(o,{...e})}):o(e)}}}]); \ No newline at end of file diff --git a/docs/assets/js/4caa95bf.ca3bb1d0.js b/docs/assets/js/4caa95bf.ca3bb1d0.js new file mode 100644 index 00000000..109ee1e0 --- /dev/null +++ b/docs/assets/js/4caa95bf.ca3bb1d0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2344],{3560:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/v1.0.0-psdb-anatomy-c1735559f93dce6d0bb3894d16047059.png"},6230:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/v1.0.0-psdb-fixed-length-encodding-dd252110b084e01cf38f21de16b3a1a5.png"},7676:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/v1.0.0-psdb-string-encoding-b1d69e9452269124d1b545020fa27d63.png"},7780:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/v1.0.0-csdb-skip-read-e3926080f7341aa7d3c6ec6d8274ea14.png"},8453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>l});var t=i(6540);const s={},r=t.createContext(s);function d(e){const n=t.useContext(r);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),t.createElement(r.Provider,{value:n},e.children)}},8645:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/v1.0.0-psdb-bool-encoding-4b154fdf5e6d79a67c91b6fb21c7209e.png"},9584:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"online-feature-store/v1.0.0/data-formats","title":"Data Formats","description":"In this section we will go through the data-formats which is at the hear of online-feature-store, it\'s inspired form other storage efficient formats like parquet & arrow, but custom made to deliver in constraint environment. The two key data-formats are:","source":"@site/docs/online-feature-store/v1.0.0/data-formats.md","sourceDirName":"online-feature-store/v1.0.0","slug":"/online-feature-store/v1.0.0/data-formats","permalink":"/BharatMLStack/online-feature-store/v1.0.0/data-formats","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/online-feature-store/v1.0.0/data-formats.md","tags":[],"version":"current","sidebarPosition":2,"frontMatter":{"title":"Data Formats","sidebar_position":2},"sidebar":"tutorialSidebar","previous":{"title":"Architecture","permalink":"/BharatMLStack/online-feature-store/v1.0.0/architecture"},"next":{"title":"Benchmarks","permalink":"/BharatMLStack/online-feature-store/v1.0.0/benchmarks"}}');var s=i(4848),r=i(8453);const d={title:"Data Formats",sidebar_position:2},l="Data Format for Permanent & Cache Storage",c={},a=[{value:"PSDB (Permanent Storage Data Block) Format",id:"psdb-permanent-storage-data-block-format",level:2},{value:"\ud83e\uddf1 Structure Overview",id:"-structure-overview",level:3},{value:"Supported Data Types",id:"supported-data-types",level:3},{value:"Scalar Types",id:"scalar-types",level:4},{value:"Vector Types",id:"vector-types",level:4},{value:"\ud83d\udce6 Encoding for Scalar Feature Type",id:"-encoding-for-scalar-feature-type",level:3},{value:"1. \ud83d\udd21 String Feature Group (Variable Length Encoding using Pascal)",id:"1--string-feature-group-variable-length-encoding-using-pascal",level:4},{value:"2. \ud83d\udfe9 Boolean Feature Group (Bit-Packed)",id:"2--boolean-feature-group-bit-packed",level:4},{value:"3. \ud83d\udccf Fixed-Length Feature Group",id:"3--fixed-length-feature-group",level:4},{value:"4. Compression",id:"4-compression",level:4},{value:"\ud83e\uddec Encoding for Vector Types",id:"-encoding-for-vector-types",level:3},{value:"Conceptual Overview",id:"conceptual-overview",level:4},{value:"Vector Length Metadata",id:"vector-length-metadata",level:4},{value:"Encoding Process",id:"encoding-process",level:4},{value:"Input Structure",id:"input-structure",level:5},{value:"Length Validation",id:"length-validation",level:5},{value:"Flattening Strategy",id:"flattening-strategy",level:5},{value:"Contiguous Layout",id:"contiguous-layout",level:5},{value:"\ud83d\udd04 Deserialization/Decoding Flow",id:"-deserializationdecoding-flow",level:3},{value:"Memory Efficiency Benefits",id:"memory-efficiency-benefits",level:3},{value:"Cache Storage Data Block (CSDB) Design",id:"cache-storage-data-block-csdb-design",level:2},{value:"Overview",id:"overview",level:3},{value:"Structure and Purpose",id:"structure-and-purpose",level:3},{value:"Core Fields and Memory Layout",id:"core-fields-and-memory-layout",level:4},{value:"Cache Types",id:"cache-types",level:4},{value:"Format & Encoding",id:"format--encoding",level:3},{value:"Differences Between In-Memory and Distributed Caching",id:"differences-between-in-memory-and-distributed-caching",level:3},{value:"Optimizations & Features",id:"optimizations--features",level:3}];function o(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"data-format-for-permanent--cache-storage",children:"Data Format for Permanent & Cache Storage"})}),"\n",(0,s.jsx)(n.p,{children:"In this section we will go through the data-formats which is at the hear of online-feature-store, it's inspired form other storage efficient formats like parquet & arrow, but custom made to deliver in constraint environment. The two key data-formats are:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"PSDB"})," - Permanent Storage Data Block used wile storing data in ScyllaDB"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"CSDB"})," - Cache Storage Data Block used while storing data in DragonflyDB or Redis, optimal for KV"]}),"\n",(0,s.jsx)(n.li,{}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"psdb-permanent-storage-data-block-format",children:"PSDB (Permanent Storage Data Block) Format"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"PSDB"})," format is a compact, versioned, and schema-aware binary layout used to store feature groups efficiently for ML inference. It supports multiple datatypes (strings, booleans, fixed-size vectors), versioning, TTL, and metadata encoding in a compact header."]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"-structure-overview",children:"\ud83e\uddf1 Structure Overview"}),"\n",(0,s.jsx)(n.p,{children:"Each PSDB block is composed of multiple byte sections:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Permanent Storage Data Block Anatomy",src:i(3560).A+"",width:"1854",height:"1102"})}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Byte"}),(0,s.jsx)(n.th,{children:"Bits"}),(0,s.jsx)(n.th,{children:"Field"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"0-1"}),(0,s.jsx)(n.td,{children:"0-15"}),(0,s.jsx)(n.td,{children:"Feature Schema Version"}),(0,s.jsx)(n.td,{children:"Version for tracking schema changes (additions/deletions) in feature group"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"2-6"}),(0,s.jsx)(n.td,{children:"16-55"}),(0,s.jsx)(n.td,{children:"Expiry Timestamp"}),(0,s.jsx)(n.td,{children:"Encoded as a compact representation, ~513 days max"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"7"}),(0,s.jsx)(n.td,{children:"56-59"}),(0,s.jsx)(n.td,{children:"Layout Version"}),(0,s.jsx)(n.td,{children:"Used to ensure backward compatibility with layout format changes"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"7"}),(0,s.jsx)(n.td,{children:"60-62"}),(0,s.jsx)(n.td,{children:"Compression Type"}),(0,s.jsx)(n.td,{children:"3-bit field specifying compression algorithm"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"7-8"}),(0,s.jsx)(n.td,{children:"63-67"}),(0,s.jsx)(n.td,{children:"Data Type"}),(0,s.jsx)(n.td,{children:"5-bit field split across bytes 7 and 8"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"8"}),(0,s.jsx)(n.td,{children:"68-71"}),(0,s.jsx)(n.td,{children:"Bool Last Valid Bit"}),(0,s.jsx)(n.td,{children:"4-bit field for last valid boolean bit"})]})]})]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"supported-data-types",children:"Supported Data Types"}),"\n",(0,s.jsx)(n.h4,{id:"scalar-types",children:"Scalar Types"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Container"}),(0,s.jsx)(n.th,{children:"Size"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"FP32"}),", ",(0,s.jsx)(n.code,{children:"FP16"}),", ",(0,s.jsx)(n.code,{children:"FP8E4M3"}),", ",(0,s.jsx)(n.code,{children:"FP8E5M2"})]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]float32"})}),(0,s.jsx)(n.td,{children:"4/2/1/1 bytes"}),(0,s.jsx)(n.td,{children:"Floating point numbers"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"Int32"}),", ",(0,s.jsx)(n.code,{children:"Int16"}),", ",(0,s.jsx)(n.code,{children:"Int8"})]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]int32"})}),(0,s.jsx)(n.td,{children:"4/2/1 bytes"}),(0,s.jsx)(n.td,{children:"Signed integers"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"Uint32"}),", ",(0,s.jsx)(n.code,{children:"Uint16"}),", ",(0,s.jsx)(n.code,{children:"Uint8"})]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]uint32"})}),(0,s.jsx)(n.td,{children:"4/2/1 bytes"}),(0,s.jsx)(n.td,{children:"Unsigned integers"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"FP64"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]float64"})}),(0,s.jsx)(n.td,{children:"8 bytes"}),(0,s.jsx)(n.td,{children:"Double precision float"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Int64"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]int64"})}),(0,s.jsx)(n.td,{children:"8 bytes"}),(0,s.jsx)(n.td,{children:"64-bit signed integer"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Uint64"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]uint64"})}),(0,s.jsx)(n.td,{children:"8 bytes"}),(0,s.jsx)(n.td,{children:"64-bit unsigned integer"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"String"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]string"})}),(0,s.jsx)(n.td,{children:"Variable"}),(0,s.jsx)(n.td,{children:"Pascal-style strings"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Bool"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[]uint8"})}),(0,s.jsx)(n.td,{children:"Bit-packed"}),(0,s.jsx)(n.td,{children:"Boolean values"})]})]})]}),"\n",(0,s.jsx)(n.h4,{id:"vector-types",children:"Vector Types"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Container"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"FP32Vector"}),", ",(0,s.jsx)(n.code,{children:"FP16Vector"}),", etc."]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]float32"})}),(0,s.jsx)(n.td,{children:"2D slices of floating point"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"Int32Vector"}),", ",(0,s.jsx)(n.code,{children:"Int16Vector"}),", etc."]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]int32"})}),(0,s.jsx)(n.td,{children:"2D slices of signed integers"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"Uint32Vector"}),", ",(0,s.jsx)(n.code,{children:"Uint16Vector"}),", etc."]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]uint32"})}),(0,s.jsx)(n.td,{children:"2D slices of unsigned integers"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"FP64Vector"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]float64"})}),(0,s.jsx)(n.td,{children:"2D slices of doubles"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Int64Vector"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]int64"})}),(0,s.jsx)(n.td,{children:"2D slices of 64-bit signed"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Uint64Vector"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]uint64"})}),(0,s.jsx)(n.td,{children:"2D slices of 64-bit unsigned"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"StringVector"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]string"})}),(0,s.jsx)(n.td,{children:"2D slices of strings"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"BoolVector"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"[][]uint8"})}),(0,s.jsx)(n.td,{children:"2D slices of bit-packed bools"})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"-encoding-for-scalar-feature-type",children:"\ud83d\udce6 Encoding for Scalar Feature Type"}),"\n",(0,s.jsx)(n.h4,{id:"1--string-feature-group-variable-length-encoding-using-pascal",children:"1. \ud83d\udd21 String Feature Group (Variable Length Encoding using Pascal)"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Max string length: ",(0,s.jsx)(n.strong,{children:"65536"})]}),"\n",(0,s.jsxs)(n.li,{children:["Format:\n",(0,s.jsx)(n.img,{alt:"PSDB String encoding",src:i(7676).A+"",width:"1488",height:"204"})]}),"\n",(0,s.jsxs)(n.li,{children:["Deserialization:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Read length prefixes"}),"\n",(0,s.jsxs)(n.li,{children:["Extract string bytes using ",(0,s.jsx)(n.code,{children:"StrLenX"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"2--boolean-feature-group-bit-packed",children:"2. \ud83d\udfe9 Boolean Feature Group (Bit-Packed)"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Saves space using bit-level packing."}),"\n",(0,s.jsxs)(n.li,{children:["Encoding:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Raw: 1 byte per feature"}),"\n",(0,s.jsx)(n.li,{children:"Bit-packed: 1 bit per boolean"}),"\n",(0,s.jsxs)(n.li,{children:["Additional index (",(0,s.jsx)(n.code,{children:"bool last idx"}),") stores where the last bit resides"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Format:\n",(0,s.jsx)(n.img,{alt:"PSDB Bool encoding",src:i(8645).A+"",width:"1120",height:"712"})]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"3--fixed-length-feature-group",children:"3. \ud83d\udccf Fixed-Length Feature Group"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["For fixed-size vectors (",(0,s.jsx)(n.code,{children:"n"})," bytes each)"]}),"\n",(0,s.jsxs)(n.li,{children:["Format:\n",(0,s.jsx)(n.img,{alt:"PSDB Fixed Length Datatype encoding",src:i(6230).A+"",width:"1122",height:"202"})]}),"\n",(0,s.jsx)(n.li,{children:"Efficient for dense numeric features like float32, int64, etc."}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"4-compression",children:"4. Compression"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"TypeNone (0)"}),": Raw storage"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"TypeZSTD (1)"}),": Compressed using Zstandard"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Compression is opportunistic. During serialization, if compressed size is not smaller, PSDB falls back to uncompressed format. It keeps the read/high througput path use less CPU cycles. Also only data part of PSDB is compressed allowing decompression only if block has a valid TTL"}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"-encoding-for-vector-types",children:"\ud83e\uddec Encoding for Vector Types"}),"\n",(0,s.jsx)(n.h4,{id:"conceptual-overview",children:"Conceptual Overview"}),"\n",(0,s.jsx)(n.p,{children:"PSDB encodes vector data by flattening multi-dimensional arrays into a single contiguous byte buffer while preserving the ability to reconstruct the original vector boundaries."}),"\n",(0,s.jsx)(n.h4,{id:"vector-length-metadata",children:"Vector Length Metadata"}),"\n",(0,s.jsx)(n.p,{children:"Each feature group maintains metadata about vector dimensions in the Feature Registry. For example, if a feature group has:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"fg1:\n version-2:\n features:\n f1: { vector_len: 6, default: [bytes] }\n f2: { vector_len: 3, default: [bytes] }\n version-1:\n features:\n f1: { vector_len: 6, default: [bytes] }\n"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Feature f1 with vector_len: 6"}),"\n",(0,s.jsx)(n.li,{children:"Feature f2 with vector_len: 3"}),"\n",(0,s.jsx)(n.li,{}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This means:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"f1"})," contains vectors of exactly 6 elements each"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"f2"})," contains vectors of exactly 3 elements each"]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"encoding-process",children:"Encoding Process"}),"\n",(0,s.jsx)(n.h5,{id:"input-structure",children:(0,s.jsx)(n.strong,{children:"Input Structure"})}),"\n",(0,s.jsx)(n.p,{children:"The serializer receives vector data as 2D slices where:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Outer dimension represents different feature instances/entities"}),"\n",(0,s.jsx)(n.li,{children:"Inner dimension represents the vector elements for each instance"}),"\n"]}),"\n",(0,s.jsx)(n.h5,{id:"length-validation",children:(0,s.jsx)(n.strong,{children:"Length Validation"})}),"\n",(0,s.jsx)(n.p,{children:"Before encoding, PSDB validates that each vector's actual length matches the declared vector_len from the feature metadata. This ensures data integrity and enables efficient decoding."}),"\n",(0,s.jsx)(n.h5,{id:"flattening-strategy",children:(0,s.jsx)(n.strong,{children:"Flattening Strategy"})}),"\n",(0,s.jsx)(n.p,{children:"Vectors are serialized in row-major order (also called C-style order):"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"All elements of the first vector are written consecutively"}),"\n",(0,s.jsx)(n.li,{children:"Followed by all elements of the second vector"}),"\n",(0,s.jsx)(n.li,{children:"And so on..."}),"\n"]}),"\n",(0,s.jsx)(n.h5,{id:"contiguous-layout",children:(0,s.jsx)(n.strong,{children:"Contiguous Layout"})}),"\n",(0,s.jsx)(n.p,{children:"The resulting byte buffer contains all vector elements placed end-to-end without gaps or separators. The decoder can reconstruct vector boundaries because it knows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The data type size (e.g., 4 bytes for float32), from feature registry"}),"\n",(0,s.jsx)(n.li,{children:"The vector length for each position, from feature registry"}),"\n",(0,s.jsx)(n.li,{children:"The total number of vectors, from feature registry"}),"\n",(0,s.jsxs)(n.li,{children:["In case of ",(0,s.jsx)(n.code,{children:"variable length"})," length is encoded into the data, like for ",(0,s.jsx)(n.code,{children:"String"})," data-type"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"-deserializationdecoding-flow",children:"\ud83d\udd04 Deserialization/Decoding Flow"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Extract version"})," from first 2 bytes."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Look up schema"})," from etcd using the version."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Determine feature shapes"})," (e.g., vector lengths)."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Slice and decode"})," data from byte buffer accordingly."]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"memory-efficiency-benefits",children:"Memory Efficiency Benefits"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"No Padding"}),": Elements are packed tightly without alignment padding"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"No Delimiters"}),": Vector boundaries are implicit, not stored explicitly"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Cache Friendly"}),": Sequential memory access patterns during encoding/decoding"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Minimal Metadata"}),": Only vector lengths are stored separately, not per-element"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"cache-storage-data-block-csdb-design",children:"Cache Storage Data Block (CSDB) Design"}),"\n",(0,s.jsx)(n.h3,{id:"overview",children:"Overview"}),"\n",(0,s.jsx)(n.p,{children:"The Cache Storage Data Block (CSDB) is a compact binary data format that encapsulates serialized data blocks for multiple feature groups. It is designed to support both in-memory and distributed caching of deserialized PSDB (Permanent Storage Data Block) content, optimizing for speed, deduplication, and minimal memory overhead."}),"\n",(0,s.jsx)(n.h3,{id:"structure-and-purpose",children:"Structure and Purpose"}),"\n",(0,s.jsx)(n.p,{children:"Each CSDB contains a mapping of feature group IDs (FG IDs) to deserialized PSDBs. For distributed systems, this structure is flattened into a serialized byte slice. The CSDB supports layout versioning for backward compatibility and negative caching for feature groups with no associated data."}),"\n",(0,s.jsx)(n.h4,{id:"core-fields-and-memory-layout",children:"Core Fields and Memory Layout"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:"type CacheStorageDataBlock struct {\n // 8-byte aligned map pointer\n FGIdToDDB map[int]*DeserializedPSDB // offset: 0\n\n // 24-byte slice (ptr, len, cap)\n serializedCSDB []byte // offset: 8\n\n // 4-byte fields\n TTL uint32 // offset: 32\n\n // 1-byte fields\n layoutVersion uint8 // offset: 36\n cacheType CacheType // offset: 37\n // 2 bytes padding to maintain 4-byte alignment\n}\n"})}),"\n",(0,s.jsx)(n.p,{children:"The structure is memory-aligned for optimal performance:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Pointers and slices are 8-byte aligned"}),"\n",(0,s.jsxs)(n.li,{children:["Smaller fields (like ",(0,s.jsx)(n.code,{children:"uint8"}),") are grouped and padded to avoid false sharing"]}),"\n",(0,s.jsx)(n.li,{children:"This layout ensures efficient use of CPU caches during access"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"cache-types",children:"Cache Types"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"In-Memory Cache"}),": Uses the ",(0,s.jsx)(n.code,{children:"FGIdToDDB"})," map directly and avoids serialization unless explicitly requested."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Distributed Cache"}),": Stores a serialized binary format in ",(0,s.jsx)(n.code,{children:"serializedCSDB"}),", which is deserialized lazily when required."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"format--encoding",children:"Format & Encoding"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"CSDB Binary Layout"}),": Serialized CSDBs follow this compact format:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"[LayoutVersion (1 byte)][FGID (2 bytes)][DataLen (2 bytes)][Data ...] \u2192 repeated per feature group\n"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["FGID and DataLen are encoded as ",(0,s.jsx)(n.code,{children:"uint16"})]}),"\n",(0,s.jsxs)(n.li,{children:["If ",(0,s.jsx)(n.code,{children:"DataLen == 0"}),", it denotes a negative cache (no data available for that FG)"]}),"\n",(0,s.jsx)(n.li,{children:"The data section contains the PSDB header and either compressed or uncompressed data"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This layout allows fast scanning and partial deserialization for selected FG IDs, making it optimal for large-scale caching systems."}),"\n",(0,s.jsx)(n.h3,{id:"differences-between-in-memory-and-distributed-caching",children:"Differences Between In-Memory and Distributed Caching"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Aspect"}),(0,s.jsx)(n.th,{children:"In-Memory CSDB"}),(0,s.jsx)(n.th,{children:"Distributed CSDB"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Storage Format"}),(0,s.jsx)(n.td,{children:"Live Go objects (map[int]*DeserializedPSDB)"}),(0,s.jsxs)(n.td,{children:["Serialized byte buffer (",(0,s.jsx)(n.code,{children:"[]byte"}),")"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Deserialization"}),(0,s.jsx)(n.td,{children:"Performed on-demand using offset map"}),(0,s.jsx)(n.td,{children:"Performed on-demand using offset map"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Compression"}),(0,s.jsx)(n.td,{children:"Optional during serialization"}),(0,s.jsx)(n.td,{children:"Typically enabled to reduce payload size"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Usage Pattern"}),(0,s.jsx)(n.td,{children:"Fast lookup in active process memory"}),(0,s.jsx)(n.td,{children:"Cross-node cache sharing and persistence"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Memory Overhead"}),(0,s.jsx)(n.td,{children:"Higher (due to live objects)"}),(0,s.jsx)(n.td,{children:"Lower (compact representation)"})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"optimizations--features",children:"Optimizations & Features"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Partial FG ID Fetch"}),": When only a subset of FG IDs is needed, CSDB avoids unnecessary deserialization of other IDs."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Negative Caching"}),": FG IDs with no data are encoded with ",(0,s.jsx)(n.code,{children:"DataLen=0"}),", saving space and avoiding repeated lookups."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Offset-Length Map"}),": During deserialization, FGID to offset+length pairs are cached internally for efficient random access."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Versioning Support"}),": Layout version is stored as the first byte to enable format upgrades while maintaining backward compatibility."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Diagram below explains how compute cycles are saved by partial de-compression."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"CSDB Partial Decompression",src:i(7780).A+"",width:"2292",height:"828"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(o,{...e})}):o(e)}}}]); \ No newline at end of file diff --git a/docs/assets/js/4df0e30b.00b3a0ff.js b/docs/assets/js/4df0e30b.00b3a0ff.js new file mode 100644 index 00000000..ffd65ccd --- /dev/null +++ b/docs/assets/js/4df0e30b.00b3a0ff.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2379],{8453:(e,n,i)=>{i.d(n,{R:()=>l,x:()=>o});var s=i(6540);const r={},t=s.createContext(r);function l(e){const n=s.useContext(t);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),s.createElement(t.Provider,{value:n},e.children)}},9680:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"numerix/v1.0.0/architecture","title":"Architecture","description":"---","source":"@site/docs/numerix/v1.0.0/architecture.md","sourceDirName":"numerix/v1.0.0","slug":"/numerix/v1.0.0/architecture","permalink":"/BharatMLStack/numerix/v1.0.0/architecture","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/numerix/v1.0.0/architecture.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"Architecture","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"v1.0.0","permalink":"/BharatMLStack/numerix/v1.0.0"},"next":{"title":"Benchmarks","permalink":"/BharatMLStack/numerix/v1.0.0/benchmarks"}}');var r=i(4848),t=i(8453);const l={title:"Architecture",sidebar_position:1},o="BharatMLStack - Numerix",a={},c=[{value:"High-Level Components",id:"high-level-components",level:2},{value:"What is SIMD?",id:"what-is-simd",level:2},{value:"Why SIMD Matters for Numerix",id:"why-simd-matters-for-numerix",level:2},{value:"Why ARM, Why LLVM",id:"why-arm-why-llvm",level:2},{value:"Request Model and Flow",id:"request-model-and-flow",level:2},{value:"Why Postfix Expressions",id:"why-postfix-expressions",level:2},{value:"gRPC Interface",id:"grpc-interface",level:2},{value:"Observability",id:"observability",level:2},{value:"Environments",id:"environments",level:2},{value:"Key Takeaways",id:"key-takeaways",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"bharatmlstack---numerix",children:"BharatMLStack - Numerix"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["Numerix is a Rust-based compute service in ",(0,r.jsx)(n.strong,{children:"BharatMLStack"})," designed for low-latency evaluation of mathematical expressions over feature matrices. Each request carries a compute_id and a matrix of features; Numerix fetches the corresponding postfix expression, maps variables to feature columns (treated as vectors), and evaluates the expression with a stack-based SIMD-optimized runtime."]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"high-level-components",children:"High-Level Components"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Tonic gRPC server (Rust)"}),": exposes ",(0,r.jsx)(n.code,{children:"Numerix/Compute"})," for low-latency requests.","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Accepts feature data as strings (for ease of use) or byte arrays (for efficient transmission)."}),"\n",(0,r.jsx)(n.li,{children:"All input data is converted internally to fp32 or fp64 vectors for evaluation."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Compute Registry (etcd)"}),": stores ",(0,r.jsx)(n.code,{children:"compute_id (int) \u2192 postfix expression"})," mappings."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Stack-based Evaluator"}),": Runs postfix expressions in linear time using a stack based approach over aligned vectors."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Vectorized Math Runtime"}),": No handwritten SIMD intrinsics; relies on ",(0,r.jsx)(n.strong,{children:"LLVM autovectorization"}),".","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Operations are intentionally simple and memory-aligned."}),"\n",(0,r.jsx)(n.li,{children:"Compiler emits SIMD instructions automatically."}),"\n",(0,r.jsx)(n.li,{children:"Portable across CPU architectures (ARM & AMD)."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Metrics and Health"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Latency, RPS, and error rates via ",(0,r.jsx)(n.strong,{children:"Datadog/DogStatsD"})," UDP client."]}),"\n",(0,r.jsxs)(n.li,{children:["Minimal HTTP endpoints (",(0,r.jsx)(n.code,{children:"/health"}),", optional ",(0,r.jsx)(n.code,{children:"/metrics"}),") for diagnostics."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"what-is-simd",children:"What is SIMD?"}),"\n",(0,r.jsx)(n.p,{children:"SIMD (Single Instruction, Multiple Data) is a CPU feature that allows a single instruction to operate on multiple data points at once. In Numerix, this means that operations on feature vectors can be executed in parallel, making evaluation of mathematical expressions faster and more predictable."}),"\n",(0,r.jsx)(n.h2,{id:"why-simd-matters-for-numerix",children:"Why SIMD Matters for Numerix"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Postfix expressions operate on vectors (columns of the input matrix)."}),"\n",(0,r.jsx)(n.li,{children:"SIMD allows multiple elements of these vectors to be processed in one CPU instruction, rather than element-by-element."}),"\n",(0,r.jsx)(n.li,{children:"This results in low-latency, high-throughput computation without the need for handwritten intrinsics \u2014 the compiler handles the vectorization automatically."}),"\n"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"why-arm-why-llvm",children:"Why ARM, Why LLVM"}),"\n",(0,r.jsxs)(n.p,{children:["During design exploration, we tested SIMD on different architectures and found ",(0,r.jsx)(n.strong,{children:"ARM (AArch64)"})," with NEON/SVE/SVE2 provided excellent performance for our workloads."]}),"\n",(0,r.jsxs)(n.p,{children:["Instead of writing custom intrinsics, Numerix ",(0,r.jsx)(n.strong,{children:"compiles with SIMD flags"})," and lets LLVM handle vectorization:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'RUSTFLAGS="-C target-feature=+neon,+sve,+sve2" \\\ncargo build --release --target aarch64-unknown-linux-gnu\n'})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"This approach works well because operations are straightforward, data is aligned, and compiler auto-vectorization is reliable."}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"AMD/x86 builds are equally supported \u2014 enabling their SIMD extensions is just a matter of changing build flags."}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"request-model-and-flow",children:"Request Model and Flow"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["Client calls gRPC ",(0,r.jsx)(n.code,{children:"numerix.Numerix/Compute"})," with:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"schema"}),": ordered feature names"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"entity_scores"}),": per-entity vectors (string or bytes)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"compute_id"}),": integer identifier for the expression"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"data_type"})," (optional): e.g., ",(0,r.jsx)(n.code,{children:"fp32"})," or ",(0,r.jsx)(n.code,{children:"fp64"})]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Service fetches the postfix expression for ",(0,r.jsx)(n.code,{children:"compute_id"})," which was pre-fetched from ",(0,r.jsx)(n.code,{children:"etcd"}),"."]}),"\n",(0,r.jsx)(n.li,{children:"Request is validated for schema and data shape."}),"\n",(0,r.jsx)(n.li,{children:"The stack-based evaluator executes the expression in O(n) over tokens, with vectorized inner operations."}),"\n",(0,r.jsxs)(n.li,{children:["Response returns ",(0,r.jsx)(n.code,{children:"computation_score_data"})," or a structured ",(0,r.jsx)(n.code,{children:"error"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"why-postfix-expressions",children:"Why Postfix Expressions"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Stored in etcd"})," as postfix (Reverse Polish) notation."]}),"\n",(0,r.jsx)(n.li,{children:"Postfix makes evaluation parser-free and linear time."}),"\n",(0,r.jsxs)(n.li,{children:["Execution uses a stack machine:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Push operands (feature vectors)."}),"\n",(0,r.jsx)(n.li,{children:"Pop, compute, and push results for each operator."}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.li,{children:"Benefits: predictable runtime, compiler-friendly loops, cache efficiency."}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"grpc-interface",children:"gRPC Interface"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Service:"})," ",(0,r.jsx)(n.code,{children:"numerix.Numerix"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"RPC:"})," ",(0,r.jsx)(n.code,{children:"Compute(NumerixRequestProto) \u2192 NumerixResponseProto"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Request fields:"})," ",(0,r.jsx)(n.code,{children:"schema"}),", ",(0,r.jsx)(n.code,{children:"entity_scores"}),", ",(0,r.jsx)(n.code,{children:"compute_id"}),", optional ",(0,r.jsx)(n.code,{children:"data_type"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Response fields:"})," ",(0,r.jsx)(n.code,{children:"computation_score_data"})," or ",(0,r.jsx)(n.code,{children:"error"})]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Example (grpcurl):"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'grpcurl -plaintext \\\n -import-path ./numerix/src/protos/proto \\\n -proto numerix.proto \\\n -d \'{\n "entityScoreData": {\n "schema": ["feature1", "feature2"],\n "entityScores": [ { "stringData": { "values": ["1.0", "2.0"] } } ],\n "computeId": "1001",\n "dataType": "fp32"\n }\n }\' \\\n localhost:8080 numerix.Numerix/Compute\n'})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"observability",children:"Observability"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Datadog (DogStatsD)"})," metrics publication via UDP client:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Latency (P50/P95/P99), error rate, RPS, internal failures"}),"\n",(0,r.jsx)(n.li,{children:"Configurable sampling rate via environment variables"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Optional ",(0,r.jsx)(n.code,{children:"/metrics"})," HTTP endpoint can be enabled for local debugging."]}),"\n"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"environments",children:"Environments"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Kubernetes (K8s), including GKE and EKS"}),"\n",(0,r.jsx)(n.li,{children:"Multi-arch builds: amd64, arm64."}),"\n",(0,r.jsx)(n.li,{children:"ARM builds ship with NEON/SVE/SVE2 enabled."}),"\n"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"key-takeaways",children:"Key Takeaways"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Minimal service surface: ",(0,r.jsx)(n.strong,{children:"gRPC + etcd"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"No custom intrinsics"})," \u2014 portable across ",(0,r.jsx)(n.strong,{children:"ARM & AMD"})," via compiler flags."]}),"\n",(0,r.jsx)(n.li,{children:"Supports both string and byte input, internally converted to aligned fp32/fp64 vectors."}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Stack-based postfix evaluation"})," : linear time, cache-friendly."]}),"\n",(0,r.jsx)(n.li,{children:"Predictable, ultra-low-latency performance."}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,r.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,r.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\ud83d\udcac ",(0,r.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,r.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,r.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,r.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,r.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,r.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)("div",{align:"center",children:(0,r.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,r.jsx)("div",{align:"center",children:(0,r.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/docs/assets/js/50899a24.c0cfae29.js b/docs/assets/js/50899a24.c0cfae29.js new file mode 100644 index 00000000..70349c40 --- /dev/null +++ b/docs/assets/js/50899a24.c0cfae29.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1009],{1008:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Numerix","description":"Numerix is a mathematical compute engine for BharatML Stack. It is used to perform mathematical operations on matrices and vectors.","slug":"/category/numerix","permalink":"/BharatMLStack/category/numerix","sidebar":"tutorialSidebar","navigation":{"previous":{"title":"Spark client","permalink":"/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client"},"next":{"title":"v1.0.0","permalink":"/BharatMLStack/numerix/v1.0.0"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/5e95c892.a6c239e7.js b/docs/assets/js/5e95c892.7a2663a1.js similarity index 62% rename from docs/assets/js/5e95c892.a6c239e7.js rename to docs/assets/js/5e95c892.7a2663a1.js index 80ddfbad..899b5397 100644 --- a/docs/assets/js/5e95c892.a6c239e7.js +++ b/docs/assets/js/5e95c892.7a2663a1.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9647],{7121:(e,s,r)=>{r.r(s),r.d(s,{default:()=>l});r(6540);var c=r(4164),u=r(5500),a=r(7559),d=r(2831),n=r(1656),t=r(4848);function l(e){return(0,t.jsx)(u.e3,{className:(0,c.A)(a.G.wrapper.docsPages),children:(0,t.jsx)(n.A,{children:(0,d.v)(e.route.routes)})})}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9647],{7121:(e,s,r)=>{r.r(s),r.d(s,{default:()=>l});r(6540);var c=r(4164),u=r(7559),a=r(5500),d=r(2831),n=r(1656),t=r(4848);function l(e){return(0,t.jsx)(a.e3,{className:(0,c.A)(u.G.wrapper.docsPages),children:(0,t.jsx)(n.A,{children:(0,d.v)(e.route.routes)})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/621db11d.1a835b77.js b/docs/assets/js/621db11d.1a835b77.js new file mode 100644 index 00000000..f2d6d885 --- /dev/null +++ b/docs/assets/js/621db11d.1a835b77.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4212],{3250:(t,s,e)=>{e.r(s),e.d(s,{default:()=>m});e(6540);var a=e(4164),o=e(5500),r=e(7559),u=e(6461),l=e(8027),n=e(1463),i=e(1107),c=e(6382);const h={authorListItem:"authorListItem_n3yI"};var g=e(4848);function p({author:t}){return(0,g.jsx)("li",{className:h.authorListItem,children:(0,g.jsx)(c.A,{as:"h2",author:t,count:t.count})})}function d({authors:t}){return(0,g.jsx)("section",{className:(0,a.A)("margin-vert--lg",h.authorsListSection),children:(0,g.jsx)("ul",{children:t.map(t=>(0,g.jsx)(p,{author:t},t.key))})})}function m({authors:t,sidebar:s}){const e=(0,u.uz)();return(0,g.jsxs)(o.e3,{className:(0,a.A)(r.G.wrapper.blogPages,r.G.page.blogAuthorsListPage),children:[(0,g.jsx)(o.be,{title:e}),(0,g.jsx)(n.A,{tag:"blog_authors_list"}),(0,g.jsxs)(l.A,{sidebar:s,children:[(0,g.jsx)(i.A,{as:"h1",children:e}),(0,g.jsx)(d,{authors:t})]})]})}},6461:(t,s,e)=>{e.d(s,{ZD:()=>u,uz:()=>l});e(6540);var a=e(1312),o=e(5846);e(4848);function r(){const{selectMessage:t}=(0,o.W)();return s=>t(s,(0,a.T)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:s}))}function u(t){const s=r();return(0,a.T)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:s(t.count),tagName:t.label})}const l=()=>(0,a.T)({id:"theme.blog.authorsList.pageTitle",message:"Authors",description:"The title of the authors page"})}}]); \ No newline at end of file diff --git a/docs/assets/js/621db11d.515621df.js b/docs/assets/js/621db11d.515621df.js deleted file mode 100644 index de839fa8..00000000 --- a/docs/assets/js/621db11d.515621df.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4212],{3250:(t,s,e)=>{e.r(s),e.d(s,{default:()=>m});e(6540);var a=e(4164),o=e(5500),r=e(7559),u=e(6461),l=e(8027),n=e(1463),i=e(1107),c=e(6382);const h={authorListItem:"authorListItem_n3yI"};var g=e(4848);function p({author:t}){return(0,g.jsx)("li",{className:h.authorListItem,children:(0,g.jsx)(c.A,{as:"h2",author:t,count:t.count})})}function d({authors:t}){return(0,g.jsx)("section",{className:(0,a.A)("margin-vert--lg",h.authorsListSection),children:(0,g.jsx)("ul",{children:t.map((t=>(0,g.jsx)(p,{author:t},t.key)))})})}function m({authors:t,sidebar:s}){const e=(0,u.uz)();return(0,g.jsxs)(o.e3,{className:(0,a.A)(r.G.wrapper.blogPages,r.G.page.blogAuthorsListPage),children:[(0,g.jsx)(o.be,{title:e}),(0,g.jsx)(n.A,{tag:"blog_authors_list"}),(0,g.jsxs)(l.A,{sidebar:s,children:[(0,g.jsx)(i.A,{as:"h1",children:e}),(0,g.jsx)(d,{authors:t})]})]})}},6461:(t,s,e)=>{e.d(s,{ZD:()=>u,uz:()=>l});e(6540);var a=e(1312),o=e(5846);e(4848);function r(){const{selectMessage:t}=(0,o.W)();return s=>t(s,(0,a.T)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:s}))}function u(t){const s=r();return(0,a.T)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:s(t.count),tagName:t.label})}const l=()=>(0,a.T)({id:"theme.blog.authorsList.pageTitle",message:"Authors",description:"The title of the authors page"})}}]); \ No newline at end of file diff --git a/docs/assets/js/6479fb86.96631f8d.js b/docs/assets/js/6479fb86.96631f8d.js new file mode 100644 index 00000000..6f77cfc2 --- /dev/null +++ b/docs/assets/js/6479fb86.96631f8d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5579],{3751:e=>{e.exports=JSON.parse('{"archive":{"blogPosts":[{"id":"post-five","metadata":{"permalink":"/BharatMLStack/blog/post-five","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-five/index.md","source":"@site/blog/bharatmlstack-history/post-five/index.md","title":"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale","description":"BharatMLStack","date":"2025-06-02T00:00:00.000Z","tags":[{"inline":true,"label":"llm","permalink":"/BharatMLStack/blog/tags/llm"},{"inline":true,"label":"vllm","permalink":"/BharatMLStack/blog/tags/vllm"},{"inline":true,"label":"tensorrt-llm","permalink":"/BharatMLStack/blog/tags/tensorrt-llm"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"},{"inline":true,"label":"bharatmlstack","permalink":"/BharatMLStack/blog/tags/bharatmlstack"}],"readingTime":4.93,"hasTruncateMarker":false,"authors":[{"name":"Jaya Kumar","title":"Lead ML Engineer @ Meesho","url":"https://github.com/jayakommuru","imageURL":"https://github.com/jayakommuru.png","key":"jaya","page":null}],"frontMatter":{"slug":"post-five","title":"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale","authors":["jaya"],"date":"2025-6-2","tags":["llm","vllm","tensorrt-llm","mlplatform","meesho","bharatmlstack"]},"unlisted":false,"nextItem":{"title":"Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving","permalink":"/BharatMLStack/blog/post-three"}},"content":"![BharatMLStack](./bms.png)\\n## LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale\\n\\nRaw execution of Large Language Models is inherently expensive and memory-intensive. To achieve sub-second latency and high throughput, we implement a multi-layered optimization strategy that targets the entire inference stack\u2014from memory management to kernel execution.\\n\\n## 1. Advanced Memory Management: Paged & Prefix KV Caching\\n\\nThe most significant bottleneck in LLM inference is not always compute, but memory bandwidth\u2014specifically managing the Key-Value (KV) cache.\\n\\n### Paged KV caching\\n\\nStandard caching suffers from fragmentation. We use **Paged KV caching**, which operates similarly to an operating system\'s virtual memory: the KV cache is divided into non-contiguous blocks. This lets us serve larger batch sizes without running out of memory.\\n\\n### KV cache quantization\\n\\nTo further maximize available memory, we implement **KV cache quantization** (e.g., FP8). By compressing stored attention keys and values from 16-bit to 8-bit, we nearly double the effective context window capacity of the GPU, allowing longer conversations or larger batches without materially degrading quality.\\n\\n### Prefix caching (the \\"voice bot\\" optimizer)\\n\\nFor use cases like GenAI voice bots where the system prompt (e.g., \\"You are a helpful assistant...\\") is static across thousands of requests, we enable **prefix caching**.\\n\\n- **Impact**: By reusing pre-computed KV states for common prefixes, we achieve a cache hit rate of ~90%. This reduces **Time To First Token (TTFT)** by skipping redundant computation of the system prompt.\\n\\n## 2. Aggressive Quantization (INT4 AWQ & FP8)\\n\\nRunning models in their native 16-bit precision (BF16) restricts maximum batch size and throughput. We use quantization to shrink model weights without sacrificing accuracy.\\n\\n### INT4 AWQ (Activation-aware Weight Quantization)\\n\\nFor the Llama 3 family, we use **AWQ** to compress weights to 4 bits. This reduces model size by ~75%, allowing larger models to fit into L4 GPU memory and significantly improving token generation speed.\\n\\n### FP8 precision\\n\\nFor NVIDIA Hopper (H100) architectures, we are exploring **FP8 quantization**, leveraging native FP8 tensor cores to accelerate matrix multiplications while maintaining a higher dynamic range than integer quantization.\\n\\n- **Verification**: We validate quantized models by comparing dot-product similarity of embeddings against the FP16 baseline, consistently achieving **>99% similarity**.\\n\\n## 3. Kernel Fusion & Custom Plugins\\n\\nTo minimize overhead from launching thousands of small GPU operations, we fuse them into monolithic kernels using NVIDIA TensorRT plugins.\\n\\n- **Flash attention & FMHA**: We enable **Fused Multi-Head Attention (FMHA)** combined with flash attention to reduce memory reads/writes.\\n- **GEMM plugins**: We use specialized **GEMM** plugins to accelerate transformer linear layers.\\n- **Removing input padding**: Instead of padding short sequences to match the longest, we remove input padding so the GPU processes only valid tokens.\\n\\n## 4. Inflight (Continuous) Batching\\n\\nTraditional static batching waits for all requests in a batch to finish before returning results\u2014so one long response delays everyone else.\\n\\nWe implement **inflight batching**: as soon as one request completes, its slot is freed and filled by a new request from the queue. This keeps GPUs saturated and decouples latency of short queries from long ones.\\n\\n## 5. Parallelism Strategies: Scaling Beyond One GPU\\n\\nFor large models (e.g., 70B+ parameters) that cannot fit into the VRAM of a single GPU, we use parallelism strategies.\\n\\n- **Tensor parallelism (TP)**: Split weight matrices across multiple GPUs (e.g., 4\xd7 L4 or 8\xd7 A100). Each GPU computes a shard and outputs are reduced at every layer.\\n- **Pipeline parallelism (PP)**: Split model layers across GPUs to pipeline compute (e.g., while one GPU computes later layers for Request A, another starts early layers for Request B).\\n\\n## 6. Speculative Decoding\\n\\nTo reduce inter-token latency (ITL), we explore **speculative decoding**.\\n\\n- **Mechanism**: A smaller, faster \\"draft\\" model speculatively generates a short token sequence (e.g., 5 tokens).\\n- **Verification**: The larger target model verifies those tokens in one parallel forward pass. If correct, we effectively generate multiple tokens per large-model step; if not, we discard and regenerate. This is effective for predictable text, improving perceived generation speed.\\n\\n## Few Benchmarks\\n\\nBelow are a couple of representative use cases and performance numbers.\\n\\n### Search query rewriting\\n\\n- **LLM**: Fine-tuned llama-3.2-1B\\n- **Input & output token length**: ~10\u201320\\n- **Response type**: Non-streaming\\n\\n| Inference runtime | Hardware | Max requests/sec | Max p99 latency |\\n| --- | --- | ---: | ---: |\\n| TensorRT-LLM | 4 \xd7 L4 GPUs (multi-GPU) | 1000 | 95 ms |\\n| TensorRT-LLM | 1 \xd7 A100 40 GB GPU | 1000 | 69 ms |\\n\\n### Voice bot query\\n\\n- **LLM**: Llama-3.1-8B\\n- **Input token length**: ~1900\u20132000\\n- **Output token length**: ~200\\n- **Response type**: Streaming\\n\\n| Inference runtime | Concurrency | p99 TTFT (ms) | p99 ITL (ms) | Token throughput (tokens/sec) | Request throughput (req/sec) | Hardware |\\n| --- | ---: | ---: | ---: | ---: | ---: | --- |\\n| TensorRT-LLM | 1 | 36.27 | 22.78 | 45.66 | 0.23 | L4 |\\n| TensorRT-LLM | 2 | 49.81 | 23.21 | 89.37 | 0.45 | L4 |\\n| TensorRT-LLM | 4 | 55.33 | 36.62 | 153.39 | 0.78 | L4 |\\n| TensorRT-LLM | 8 | 66.5 | 39.11 | 279.88 | 1.47 | L4 |\\n| TensorRT-LLM | 16 | 131.8 | 30.39 | 547.8 | 2.77 | L4 |\\n| TensorRT-LLM | 32 | 277.22 | 48.02 | 925.7 | 4.78 | L4 |\\n| TensorRT-LLM | 64 | 498.52 | 71.62 | 1,164.40 | 6.2 | L4 |\\n| TensorRT-LLM | 128 | 677.31 | 120.37 | 1,445.18 | 7.69 | L4 |\\n| TensorRT-LLM | 256 | 1,926.31 | 216.88 | 1,600.81 | 8.52 | L4 |\\n| TensorRT-LLM | 1 | 21.17 | 9.24 | 130.05 | 0.68 | A100 |\\n| TensorRT-LLM | 2 | 25.78 | 9.21 | 264.5 | 1.35 | A100 |\\n| TensorRT-LLM | 4 | 28.52 | 10.99 | 437.69 | 2.27 | A100 |\\n| TensorRT-LLM | 8 | 34.4 | 12.61 | 760.49 | 3.96 | A100 |\\n| TensorRT-LLM | 16 | 68.03 | 14.32 | 1,343.80 | 7.01 | A100 |\\n| TensorRT-LLM | 32 | 185.96 | 16.82 | 2,287.30 | 11.92 | A100 |\\n| TensorRT-LLM | 64 | 136.87 | 21.17 | 3,625.22 | 18.89 | A100 |\\n| TensorRT-LLM | 128 | 463.78 | 34.15 | 4,456.51 | 23.24 | A100 |\\n| TensorRT-LLM | 256 | 890.12 | 59.18 | 5,188.24 | 27.05 | A100 |\\n\\n## Conclusion\\n\\nHigh-performance LLM inference is fundamentally a systems engineering problem: memory efficiency, kernel execution, batching strategy, and parallelism determine real-world latency and throughput. Techniques such as paged KV caching, aggressive quantization, kernel fusion, and inflight batching improve GPU utilization while reducing latency and memory pressure.\\n\\nThese optimizations enable the platform to deliver sub-second responses, sustain high concurrency, and efficiently serve both lightweight and long-context workloads. By continuously optimizing across the full inference stack, we keep LLM serving scalable, cost-efficient, and production-ready for real-time AI applications."},{"id":"post-three","metadata":{"permalink":"/BharatMLStack/blog/post-three","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-four/index.md","source":"@site/blog/bharatmlstack-history/post-four/index.md","title":"Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving","description":"BharatMLStack","date":"2025-03-29T00:00:00.000Z","tags":[{"inline":true,"label":"llm","permalink":"/BharatMLStack/blog/tags/llm"},{"inline":true,"label":"vllm","permalink":"/BharatMLStack/blog/tags/vllm"},{"inline":true,"label":"tensorrt-llm","permalink":"/BharatMLStack/blog/tags/tensorrt-llm"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"},{"inline":true,"label":"bharatmlstack","permalink":"/BharatMLStack/blog/tags/bharatmlstack"}],"readingTime":13.38,"hasTruncateMarker":false,"authors":[{"name":"Jaya Kumar","title":"Lead ML Engineer @ Meesho","url":"https://github.com/jayakommuru","imageURL":"https://github.com/jayakommuru.png","key":"jaya","page":null}],"frontMatter":{"slug":"post-three","title":"Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving","authors":["jaya"],"date":"2025-3-29","tags":["llm","vllm","tensorrt-llm","mlplatform","meesho","bharatmlstack"]},"unlisted":false,"prevItem":{"title":"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale","permalink":"/BharatMLStack/blog/post-five"},"nextItem":{"title":"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search","permalink":"/BharatMLStack/blog/post-three"}},"content":"![BharatMLStack](./bms.png)\\n## Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving\\n\\n\\n\\nServing large language models in production introduces new challenges across infrastructure, performance optimization, and operational lifecycle management. The LLM Inference Platform addresses these challenges by providing a unified system for deploying and managing open-source and fine-tuned LLMs at scale.\\n\\nThe platform implements a complete LLMOps lifecycle \u2014 from model registration and automated compilation to deployment, runtime optimization, and monitoring. Designed as a self-service environment, users can onboard models directly from open repositories such as Hugging Face or upload custom fine-tuned models, and deploy them using a single-click workflow with no manual infrastructure or configuration steps required.\\n\\nIn addition to fully automated deployment, the platform allows users to select and apply custom inference optimization techniques \u2014 such as quantization strategies, batching configurations, and runtime-specific performance enhancements \u2014 enabling teams to balance latency, throughput, and cost based on their use case. The goal is to reduce operational friction while enabling high-performance, production-grade LLM inference.\\n\\n## Why LLM Inference Is not just bigger ML model serving\\n\\nLarge language model (LLM) inference introduces a fundamentally different set of challenges compared to traditional machine learning inference. While classical ML models typically perform a single forward pass to produce a fixed prediction, LLMs operate as autoregressive systems, generating outputs token by token based on previously generated context. This difference dramatically changes how inference systems must be designed, optimized, and scaled.\\n\\n### Autoregressive Generation and Sequential Computation:\\n\\nUnlike traditional models such as classifiers or recommenders \u2014 where inference cost is relatively constant \u2014 LLMs generate responses incrementally. Each new token depends on all previously generated tokens, making inference inherently sequential and dynamic. This means latency and compute requirements vary significantly depending on prompt length and output size, introducing complexity in scheduling and resource allocation.\\nBecause tokens cannot be generated fully in parallel during decoding, GPUs may become underutilized without specialized batching and scheduling strategies. This has led to the development of dedicated LLM inference engines optimized for token-level execution.\\n\\n### Prefill and Decode Phases:\\n\\nLLM inference typically consists of two distinct stages:\\n\\n- Prefill phase \u2014 the model processes the input prompt and builds internal representations. This stage is compute-heavy and highly parallelizable.\\n- Decode phase \u2014 the model generates tokens sequentially, predicting one token at a time using previously generated context.\\n\\nThe decode stage often becomes memory-bound rather than compute-bound, which creates new performance bottlenecks compared to traditional ML workloads.\\n\\n### Context Management and KV Caching:\\n\\nAnother fundamental difference lies in how LLMs maintain context. Transformer-based models rely on attention mechanisms that require access to past token representations. To avoid recomputing these representations repeatedly, inference engines use key-value (KV) caching, which stores intermediate activations from previous tokens.\\nKV caching significantly improves performance by eliminating redundant computation, but it introduces new challenges:\\n\\n- Memory consumption grows with sequence length and batch size\\n- GPU memory becomes a critical bottleneck\\n- Efficient memory management becomes essential for scaling concurrent requests\\n\\nThis tradeoff between compute efficiency and memory usage is unique to LLM inference workloads.\\n\\n### Dynamic and Irregular Workloads:\\n\\nTraditional ML inference typically operates on fixed-size inputs with predictable latency. In contrast, LLM requests vary widely in prompt length, output length, and runtime behavior. As a result:\\n\\n- Batch sizes must be dynamic rather than static\\n- Requests may enter and leave batches asynchronously\\n- Scheduling systems must continuously rebalance workloads to maximize GPU utilization\\n\\nThese characteristics require specialized serving architectures that differ significantly from standard ML serving pipelines.\\n\\n### Streaming and User Experience Constraints:\\n\\nAnother distinguishing factor is the expectation of real-time streaming responses. Instead of returning a single output, LLM systems often stream tokens to users as they are generated. \\nBecause of these differences \u2014 sequential generation, growing memory requirements, dynamic workloads, and streaming constraints \u2014 LLM inference cannot be treated as a simple extension of existing ML serving systems. Production platforms must incorporate specialized runtime engines, advanced optimization techniques, and observability tailored specifically to LLM workloads.\\n\\n## LLMOps: High-Level Architecture \\n\\n![LLM Architecture](./llm-plat.png)\\n\\nThe LLM Inference Framework is designed as a fully automated, end-to-end system for deploying and operating open-source and fine-tuned large language models at scale. The architecture abstracts the complexity of model optimization, hardware selection, deployment, and runtime management into a unified workflow that enables users to move from raw model weights to production-ready inference endpoints with minimal manual intervention.\\n\\nOur LLM Inference Framework is architected not just as a serving engine, but as a complete lifecycle management system. As illustrated in the high-level design below, the platform automates the journey of a model through seven distinct stages, ensuring reproducibility, performance, and scalability.\\n\\n1. Onboarding & Registration (The Source of Truth)\\n\\n The lifecycle begins with the Data Scientist or engineer.\\n\\n - Model Ingestion: Users onboard models\u2014whether open-source (Hugging Face, NeMo) or internally fine-tuned\u2014via the Truffle Box SDK/UI.\\n - LLM + Prompt Registry: Unlike traditional systems that only track model weights, our registry is a unified control plane. It stores both the Model Artifacts and the Prompt Templates. This allows Data Scientists to register and version-control prompts (e.g., \\"customer_support_v2\\") independently of the application code.\\n\\n2. The \\"Black Box\\" Build Engine\\n\\n Once a model is registered, the Automated LLM Compiler + Quantizer Module kicks off a background job on ephemeral GPU resources.\\n\\n - Transformation: The raw model is converted into a TRT-LLM Checkpoint.\\n - Quantization: The system automatically applies quantization algorithms (like INT4 AWQ or FP8) to reduce memory footprint.\\n - Engine Building: Finally, it compiles a highly optimized TRT Engine specifically tuned for the target hardware.\\n\\n3. Intelligent Profiling & Validation\\n\\n Before deployment, the new engine passes through the Hardware & Inference Runtime Profiler.\\n\\n - Benchmarking: This module empirically tests the engine against various hardware configurations (L4 vs. A100) and runtimes (TRT-LLM vs. vLLM).\\n - Optimization: It recommends the optimal configuration that meets latency SLAs (Time-To-First-Token) while minimizing cost.\\n\\n4. Smart Artifact Generation & Distribution\\n\\n To solve the Kubernetes \\"Cold Start\\" problem, the LLM Serving Artifacts Generation module packages the model using a bifurcated strategy:\\n\\n - Standard Models: Artifacts are uploaded to Cloud Storage (GCS) and downloaded by pods at startup.\\n - Very Large Models: For massive models (>8GB) where network downloads are too slow, the system pre-caches the model onto Secondary Boot Disks. These disks are attached directly to new GPU nodes during autoscaling, eliminating download wait times.\\n\\n5. Image Streaming & Deployment\\n\\n Simultaneously, the inference runtime container images are pulled from the Artifact Registry.\\n\\n - Image Streaming: We utilize container image streaming to allow pods to start initializing while the massive Triton/Dynamo container layers are still downloading, further shaving seconds off the startup time. link\\n\\n6. The Inference Runtime (Kubernetes)\\n\\n The workload lands on Kubernetes with Autoscaling.\\n\\n - Dynamic Backends: Depending on the profile generated in Stage 3, the pod initializes either TensorRT-LLM (for throughput) or vLLM (for flexibility), or spins up a Dynamo worker for distributed inference.\\n - Data Loading: The pod either downloads the model from Cloud Storage or mounts the pre-warmed Secondary Boot Disk (\\"Pull from Disk\\").\\n\\n7. Client Interaction & Observability\\n\\n Finally, the LLM Inference Client executes the request.\\n\\n - Prompt Injection: The client pulls the specific prompt template ID from the Registry, ensuring the exact versioned instructions are used.\\n - Streaming Response: The request is sent via gRPC, and tokens are streamed back to the user in real-time.\\n\\n8. Observability: Monitoring the Pulse of GenAI\\n\\n In traditional microservices, success is measured by CPU utilization and request latency (p99). For Large Language Models, these metrics are insufficient. A user doesn\'t care if the GPU is at 80% utilization; they care about how fast the first word appears and how smoothly the rest of the sentence follows.\\n\\n To capture the true user experience, our platform instrumentation focuses on three critical LLM-specific metrics:\\n\\n 1. Time to First Token (TTFT)\\n - Definition: TTFT measures the time elapsed from the moment a request is received until the very first token is generated and streamed back to the user.\\n - Why it matters: This represents the \\"Prefill Phase\\" latency\u2014the time the model takes to process the input prompt and load weights. A high TTFT makes the application feel unresponsive or \\"hung.\\"\\n - Optimization: We closely monitor TTFT to ensure our Prefix Caching is effective (aiming for high cache hitrates), which drastically lowers this metric by skipping redundant prompt processing.\\n\\n 2. Inter-Token Latency (ITL)\\n - Definition: ITL measures the average time interval between the generation of consecutive tokens during the \\"Decode Phase\\".\\n - Why it matters: This defines the \\"perceived speed\\" of reading. Even if the first token is fast (low TTFT), high ITL makes the text generation look \\"jerky\\" or slow to the user.\\n - Benchmarks: In our testing with Llama 3.1, we track p99 ITL to ensure it stays below human reading speeds to maintain a natural conversational flow.\\n\\n 3. Token Throughput vs. Request Throughput\\n - We distinguish between two types of throughput to balance system efficiency with user load:\\n - Token Throughput (tokens/sec): The total number of tokens generated across all concurrent requests. This measures the raw compute efficiency of the GPU and the effectiveness of batching.\\n - Request Throughput (req/sec): The number of distinct user queries served per second. We use this to determine autoscaling thresholds, ensuring we scale out before the queue depth impacts ITL.\\n\\n 4. The Monitoring Stack\\n - Real-time Dashboards: We utilize Grafana to visualize these streaming metrics in real-time, allowing on-call engineers to spot \\"slow generation\\" incidents that generic \\"500 error\\" alerts would miss.\\n - Request Tracing: Since Triton Inference Server does not log request payloads by default, we integrate a Helix Client to asynchronously publish request logs to Log Tables. This allows us to trace a specific \\"slow\\" request back to its prompt to understand if a complex input caused the latency spike.\\n\\n## Supported Inference backends (TensorRT LLM, Dynamo & vLLM)\\n\\nTailored for the Use Case: We do not believe in a \\"one-size-fits-all\\" approach to inference. Different use cases\u2014whether a real-time voice bot requiring ultra-lowsub-second latency or a massive reasoning task requiring huge context windows\u2014demand different runtime characteristics. Our platform is designed to be runtime-agnostic, allowing us to automatically select and tailor the best engine based on the specific requirements of the application:\\n\\n1. TensorRT-LLM: The High-Performance Standard\\n\\n Suitable for: High-throughput production workloads where latency is critical (e.g., customer support chat, real-time voice bots).\\n\\n TensorRT-LLM serves as our default backend for these scenarios. Our internal benchmarks on Llama 3.1 and 3.2 models demonstrated that a tuned TensorRT-LLM engine significantly outperforms standard runtimes, especially when utilizing INT4 AWQ and FP8 quantization .\\n\\n Key optimizations we tailor for these high-load cases include:\\n\\n - Optimized execution via TensorRT engine compilation\\n - Quantization-aware execution for reduced memory usage and improved throughput\\n - Inflight Batching: Allowing requests to be processed continuously without waiting for the entire batch to finish, drastically improving GPU utilization .\\n - Custom Plugins: Enabling specific NVIDIA plugins like the GEMM plugin and GPT Attention plugin to accelerate matrix multiplications and attention mechanisms .\\n\\n2. Dynamo: Distributed Inference for Reasoning Models\\n\\n Suitable for: Very large \\"reasoning\\" models (70B+) or scenarios requiring massive context windows where a single GPU\'s memory is insufficient.\\n\\n For these memory-bound tasks, we utilize Dynamo, a low-latency distributed inference framework . Unlike monolithic servers, Dynamo disaggregates the inference process to scale resources horizontally:\\n\\n - KV Aware Routing: A specialized router directs requests to workers that already hold the relevant Key-Value (KV) cache, minimizing redundant computation .\\n - Prefill vs. Decode Split: The workload is divided into Prefill Workers (processing the prompt) and Decode Workers (generating tokens), allowing us to scale the compute-heavy \\"reading\\" phase independently from the memory-heavy \\"writing\\" phase .\\n - Distributed execution across multiple GPU resources\\n\\n3. vLLM: The Flexible Baseline\\n\\n Suitable for: Rapid prototyping, testing new model architectures, or low-traffic internal tools where ease of deployment outweighs raw throughput.\\n\\n While TensorRT-LLM is optimized for maximum speed, vLLM provides a robust and flexible baseline .\\n\\n - High throughput through dynamic batching and efficient memory utilization\\n - Paged KV cache management for handling long contexts and concurrent requests\\n - Strong support for open-source model ecosystems\\n - Rapid Adoption: It allows us to onboard new model architectures immediately without waiting for a custom TensorRT build.\\n - Benchmarking Insight: In our internal tests, vLLM provided a strong baseline but often lacked the specific max-token optimizations present in our custom TRT engines . We use it strategically for initial testing before committing to a full TensorRT optimization pipeline.\\n\\n## Conclusion\\n\\nLarge language model inference introduces a fundamentally new class of infrastructure challenges\u2014where performance is governed not just by raw compute, but by memory efficiency, intelligent scheduling, runtime specialization, and lifecycle automation. Unlike traditional ML serving, LLM inference requires systems that understand token-level execution, manage rapidly growing context state, and continuously balance latency, throughput, and cost under highly dynamic workloads.\\n\\nThe LLM Inference Framework addresses these challenges by transforming inference into a fully automated, reproducible lifecycle\u2014from model onboarding and compilation to deployment, optimization, and observability. By integrating automated quantization and engine compilation, intelligent runtime selection, cold-start mitigation strategies, and LLM-specific observability metrics such as Time-to-First-Token and Inter-Token Latency, the platform ensures both high performance and operational simplicity.\\n\\nEqually important, the framework is designed with flexibility and future evolution in mind. Its runtime-agnostic architecture enables seamless adoption of emerging inference engines, hardware accelerators, and optimization techniques without requiring platform redesign. This ensures that teams can continuously leverage advancements in the rapidly evolving LLM ecosystem while maintaining consistent operational workflows.\\n\\nUltimately, the goal of the platform is to make production-scale LLM deployment as seamless and reliable as traditional software deployment\u2014allowing teams to focus on building intelligent applications rather than managing infrastructure complexity. By combining lifecycle automation, runtime optimization, and deep observability, the LLM Inference Framework provides a scalable foundation for delivering fast, cost-efficient, and production-ready LLM experiences.\\n\\n## Future Explorations\\n\\nWhile we have achieved significant milestones in latency and throughput, the landscape of GenAI is evolving rapidly. Our roadmap focuses on increasing flexibility, reducing costs, and enhancing reliability for enterprise-grade workloads. Here is what we are building next:\\n\\n- TPU Support: To diversify our hardware supply chain and further optimize cost-per-token, we are evaluating Google Cloud TPUs to bake it into our platform. By leveraging the JAX and PyTorch/XLA ecosystems, we aim to unlock the massive throughput potential of TPU v5e chips, particularly for our open-source Llama models. This will allow the hardware profiler to dynamically choose between NVIDIA GPUs and Google TPUs based on real-time availability and price-performance metrics.\\n- Multi-LoRA Serving (Serverless Experience): Currently, deploying a fine-tuned model requires a dedicated GPU. We are building support for Multi-LoRA serving, which will allow us to serve hundreds of unique, fine-tuned adapters on top of a single frozen base model. This will drastically reduce costs for multi-tenant applications, enabling a \\"serverless\\" experience where specific fine-tunes are hot-swapped instantly per request.\\n- Spot Instance Orchestration: To further optimize cloud costs, we are developing fault-tolerant mechanisms to run inference workloads on Spot Instances. By implementing aggressive checkpointing and seamless request draining, we aim to leverage cheaper, preemptible compute capacity without interrupting the user\'s streaming experience.\\n- Semantic Caching Layer: We plan to move beyond standard Prefix Caching to implement Semantic Caching. By using a vector database to fetch responses for semantically similar queries (e.g., \\"How do I reset my password?\\" vs. \\"Password reset steps\\"), we can bypass the GPU entirely for repetitive queries, reducing latency to near-zero.\\n- Context-Aware Autoscaling: Standard CPU/GPU utilization metrics are often insufficient signals for scaling LLMs. We are working on KV-cache pressure metrics for autoscaling. This ensures that we scale out before the memory fills up, preventing eviction-based slowdowns during traffic spikes.\\n- Online Evaluation & Guardrails: We are integrating a lightweight \\"Trust Layer\\" into the proxy. This will allow for low-latency input/output filtering (Guardrails) and asynchronous \\"LLM-as-a-Judge\\" evaluation pipelines to monitor response quality in production, not just system health."},{"id":"post-three","metadata":{"permalink":"/BharatMLStack/blog/post-three","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-three/index.md","source":"@site/blog/bharatmlstack-history/post-three/index.md","title":"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search","description":"BharatMLStack","date":"2024-05-21T00:00:00.000Z","tags":[{"inline":true,"label":"model-inference","permalink":"/BharatMLStack/blog/tags/model-inference"},{"inline":true,"label":"embedding-search","permalink":"/BharatMLStack/blog/tags/embedding-search"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"},{"inline":true,"label":"bharatmlstack","permalink":"/BharatMLStack/blog/tags/bharatmlstack"}],"readingTime":3.6,"hasTruncateMarker":false,"authors":[{"name":"Aditya Kumar","title":"Lead Software Engineer @ Meesho","url":"https://github.com/Adit2607","imageURL":"https://github.com/Adit2607.png","key":"aditya","page":null},{"name":"Jaya Kumar","title":"Lead ML Engineer @ Meesho","url":"https://github.com/jayakommuru","imageURL":"https://github.com/jayakommuru.png","key":"jaya","page":null},{"name":"Adarsha Das","title":"Senior Architect @ Meesho","url":"https://github.com/a0d00kc","imageURL":"https://github.com/a0d00kc.png","key":"adarsha","page":null}],"frontMatter":{"slug":"post-three","title":"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search","authors":["aditya","jaya","adarsha"],"date":"2024-05-21T00:00:00.000Z","tags":["model-inference","embedding-search","mlplatform","meesho","bharatmlstack"]},"unlisted":false,"prevItem":{"title":"Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving","permalink":"/BharatMLStack/blog/post-three"},"nextItem":{"title":"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)","permalink":"/BharatMLStack/blog/post-two"}},"content":"![BharatMLStack](./bms.png)\\n\\n## Cracking the Code: Scaling Model Inference & Real-Time Embedding Search\\n\\nBy mid-2023, we had transformed our ML stack\u2014building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:\\n\\n- \ud83d\udd39 Scaling model inference without hitting infrastructure roadblocks\\n- \ud83d\udd39 Moving embedding search from batch to real-time for candidate generation\\n\\nHere\u2019s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system.\\n\\n## Breaking Free from the Scalability Ceiling\\n\\n### The Model Serving Bottleneck\u2014A Wake-Up Call\\n\\nJuly 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue\u2014scaling our model-serving infrastructure was taking 10\u201315 minutes. In real-time ML, that\u2019s an eternity.\\nIn one of our war rooms, we ran a quick experiment:\\n\\n- \ud83d\ude80 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine.\\n- \ud83d\ude80 Fired requests and compared the outputs with our existing cloud-hosted setup.\\n- \ud83d\ude80 The results matched\u2014perfectly.\\n\\nThat moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn\'t allocate enough compute resources in time. Luckily, they did\u2014but the seed was planted.\\nThen in October, just two weeks before MBS, we got an alarming response from our infrastructure team:\\n \\"Node availability may be an issue.\\"\\nWith no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?\\n\\n- \u2705 p99 latency dropped from 90\u2013100ms to 30\u201340ms\\n- \u2705 Triton handled significantly higher throughput on fewer resources\\n- \u2705 No model changes were needed\\n\\nMBS ran without a hitch, proving that self-hosted inference was the way forward.\\n\\n### Scaling Triton on GKE\\n\\nThis left us with two choices:\\n\\n- 1\ufe0f\u20e3 Port models to a managed cloud inference service, investing time in learning a new deployment stack\\n- 2\ufe0f\u20e3 Scale our existing Triton setup on GKE, optimizing for cost and performance\\n\\nWe went with Option 2\u2014and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations.\\n\\n### Fixing the Cold Start Problem\\n\\nAs we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7\u20139 minutes to spin up.\\n\\nAfter profiling, we found the culprits:\\n\\n- Triton\u2019s base image\u2014a massive 5GB\\n- Model binaries\u2014often 1GB+\\n- Startup delay\u2014mostly due to downloading and initializing these assets\\n\\nTo fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother.\\n\\n## Embedding Search: The Last Piece of the Puzzle\\n\\nBy mid-2023, most of our ML stack had gone real-time\u2014except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system.\\n\\n### Choosing the Right Vector Database\\n\\nWe benchmarked three production-ready vector DBs across key parameters:\\n\\n- Milvus\\n- Qdrant\\n- Weaviate\\n\\nAfter extensive POCs, Qdrant stood out for its:\\n\\n- \u2705 Blazing-fast search latency on high-dimensional vectors\\n- \u2705 Efficient memory usage, crucial for in-memory workloads\\n- \u2705 Support for upserts and soft deletes, vital for Ads use cases\\n- \u2705 gRPC + REST APIs, making integration seamless\\n- \u2705 Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)\\n\\nAt its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search\u2014a perfect fit for our needs.\\n\\n### Embedding Freshness & Real-Time Updates\\n\\nTo ensure embeddings stayed up to date, we built a dual ingestion pipeline:\\n\\n- \ud83d\udccc Daily Refresh: A bulk pipeline updated embeddings overnight\\n- \ud83d\udccc Real-Time Updates: Ads events triggered immediate upserts/deletes\\n\\nThis setup powered real-time \\"Similar Products\\" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.\\n\\n![Skye](./vss.png)\\n\\n## Final Takeaways: Scaling Smartly for Real-Time ML\\n\\n- \ud83d\ude80 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services\\n- \ud83d\ude80 Building a custom Triton image reduced cold starts, improving responsiveness\\n- \ud83d\ude80 Qdrant-based embedding search enabled real-time personalization at scale\\n- \ud83d\ude80 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations\\n\\nBy early 2024, Meesho\u2019s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead."},{"id":"post-two","metadata":{"permalink":"/BharatMLStack/blog/post-two","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-two/index.md","source":"@site/blog/bharatmlstack-history/post-two/index.md","title":"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)","description":"BharatMLStack","date":"2023-04-10T00:00:00.000Z","tags":[{"inline":true,"label":"inferflow","permalink":"/BharatMLStack/blog/tags/inferflow"},{"inline":true,"label":"interaction-store","permalink":"/BharatMLStack/blog/tags/interaction-store"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"},{"inline":true,"label":"bharatmlstack","permalink":"/BharatMLStack/blog/tags/bharatmlstack"}],"readingTime":6.31,"hasTruncateMarker":false,"authors":[{"name":"Bhawani Singh","title":"Architect @ Meesho","url":"https://github.com/singh-bhawani","imageURL":"https://github.com/singh-bhawani.png","key":"bhawani","page":null},{"name":"Jigar Dave","title":"Lead Software Engineer @ Meesho","url":"https://github.com/jigarpatel26","imageURL":"https://github.com/jigarpatel26.png","key":"jigar","page":null},{"name":"Adarsha Das","title":"Senior Architect @ Meesho","url":"https://github.com/a0d00kc","imageURL":"https://github.com/a0d00kc.png","key":"adarsha","page":null}],"frontMatter":{"slug":"post-two","title":"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)","authors":["bhawani","jigar","adarsha"],"date":"2023-4-10","tags":["inferflow","interaction-store","mlplatform","meesho","bharatmlstack"]},"unlisted":false,"prevItem":{"title":"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search","permalink":"/BharatMLStack/blog/post-three"},"nextItem":{"title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","permalink":"/BharatMLStack/blog/post-one"}},"content":"![BharatMLStack](./bms.png)\\n## Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)\\n\\nBy late 2022, we had built something we were truly proud of\u2014a real-time ML serving system with a DAG-based executor, a feature store, and an interaction store powering key ranking and personalization models. It was a major milestone, the culmination of months of effort from data scientists, ML engineers, and backend teams. Our system was live, and we were ready to push the boundaries of experimentation.\\nAnd it worked. Mostly.\\nBut soon, cracks appeared. Every new model needed custom feature retrieval logic, DAGs became dense and unmanageable, and scaling turned into a constant firefight. Costs surged, and infra bottlenecks slowed experimentation. Our system worked, but it wasn\u2019t built for scale.\\nThis is the story of how we tackled these challenges\u2014building Inferflow for seamless feature retrieval, optimizing real-time infra, and cutting costs while scaling to millions of QPS.\\n\\n### The Cost of Success\\nEvery new Ranker model required its own feature set, often pulling from different entities. Each addition meant:\\n\\n- Adding new DAG nodes in IOP\\n- Writing custom logic to fetch features from multiple sources (e.g., user, product, user \xd7 category)\\n- Inferring intermediate features (e.g., extracting category from a product to fetch user \xd7 category data)\\n- Optimizing I/O and dealing with the inevitable bugs\\n\\nWhat began as clean DAGs soon turned into a tangled web of cross-dependent graphs. Every experimentation cycle meant new nodes, new dependencies, and slower iterations.\\n\\n### Scaling Pains (and Cassandra\u2019s Limits)\\nAt some point, we were hitting:\\n\\n- 250\u2013300K reads/sec\\n- 1M writes/sec (during lean hours)\\n\\nAll of this ran on Cassandra. While its distributed architecture had been proven in production, operating large-scale clusters came with considerable infrastructure overhead. Our proof-of-concept (POC) demonstrated throughput of around 100K ops/sec, but as we scaled further, the challenges grew. Ensuring node health, optimizing compaction, and maintaining storage balance became increasingly demanding. We also observed latency spikes under heavy load, alongside a sharp increase in total cost of ownership.\\n\\n### Interaction Store Woes\\nOur interaction store was another ticking time bomb:\\n\\n- \ud83d\udea8 Clusters kept growing in size and cost\\n- \ud83d\udea8 Latency spikes became increasingly frequent\\n- \ud83d\udea8 The DMC proxy occasionally lost locality of nodes against shards, causing cross-node communication and degraded performance\\n\\nEach time this happened, we had to manually rebalance shards just to restore stable latency, making operations unsustainable at scale.\\n\\n### Silver Linings\\nDespite the chaos, the system was live and delivering value:\\n\\n- Real-time infrastructure was in production\\n- Costs dropped by 60\u201370% compared to offline personalization\\n- New experiments rolled out faster and more successfully\\n- User engagement metrics improved\\n\\nIt wasn\u2019t perfect. It was far from easy. But it worked\u2014and that counted for a lot.\\n\\n### Round Two: Solving the Top 2 Bottlenecks\\nWith the first-gen system stretched to its limits, we stepped back. Conversations with data scientists and backend engineers revealed three recurring pain points:\\n\\n1. Coding feature retrieval logic for every new model was becoming unsustainable\\n2. ML scale was exploding\u2014bringing rising infra costs with it\\n3. Real-time embedding search was the next big unlock\\n\\nWe tackled them one by one\u2014starting with the biggest pain point.\\n\\n#### Problem 1: No-Code Feature Retrieval for Model Inference\\nWe noticed a pattern: for personalized ranking, models needed features from:\\n\\n- \u2705 Product\\n- \u2705 User\\n- \u2705 User \xd7 Category\\n- \u2705 Region, cohort, sub-category, etc.\\n\\nA key insight emerged: Entities that contribute features for a model always map back to the context entities.\\n\\n![MP Dag](./mp-dag.png)\\n\\nWith this, we designed Inferflow, a graph-driven feature retrieval and model orchestration system:\\n\\n- 1\ufe0f\u20e3 Inferflow takes a modelId and context IDs (e.g., userId, productIds)\\n- 2\ufe0f\u20e3 Loads a pre-defined feature retrieval graph from ZooKeeper\\n- 3\ufe0f\u20e3 Executes the graph to resolve entity relationships dynamically\\n- 4\ufe0f\u20e3 Outputs a 2D matrix of feature vectors\\n\\n\ud83d\udca1 The impact?\\n\\n- \ud83d\ude80 No more custom feature retrieval code\u2014just graph updates in config\\n- \ud83d\ude80 Feature consistency across experiments\\n- \ud83d\ude80 Faster iteration cycles for ranking, fraud detection, and beyond\\n\\nHere\u2019s a visual example that shows how this graph plays out during execution. We further extended the graph to call multiple models as needed:\\n![MP matrix](./mp-matrix.png)\\nWe built Inferflow in GoLang, using gRPC and Proto3 serialization for efficiency.\\n\\n#### Problem 2: Scaling Without Breaking the Bank\\nWith more ML use cases coming online, we needed to cut costs without compromising performance. We focused on:\\n\\n- \ud83d\udd39 Online Feature Store\\n- \ud83d\udd39 Interaction Store\\n\\n#### Optimizing the Online Feature Store\\nOur costs were concentrated in:\\n\\n- \ud83d\udccc Database (Cassandra)\\n- \ud83d\udccc Cache (Redis)\\n- \ud83d\udccc Running Pods (Java services)\\n\\n1\ufe0f\u20e3 Replacing Cassandra with ScyllaDB\\nAs we hit the operational limits of large Cassandra clusters, we transitioned to ScyllaDB, which offered a seamless drop-in replacement without major code changes. The switch brought significant benefits:\\n\\n- Throughput: Matched or exceeded Cassandra\'s performance under identical workloads, even under high concurrency.\\n- Latency: Achieved consistently lower P99 latencies due to ScyllaDB\'s shard-per-core architecture and better I/O utilization.\\n- Cost Efficiency: Reduced infra footprint by ~70% through better CPU and memory efficiency, eliminating the need for over-provisioned nodes.\\n\\n2\ufe0f\u20e3 Finding the Right Cache\\nTo reduce backend load and improve response times, we benchmarked multiple caching solutions\u2014Memcached, KeyDB, and Dragonfly\u2014under real production traffic patterns. Dragonfly stood out due to its robust architecture and operational simplicity:\\n\\n- Data Skew Handling: Efficiently managed extreme key hotness and uneven access patterns without performance degradation.\\n- Throughput: Delivered consistently high throughput, even with large object sizes and concurrent access.\\n- Ease of Adoption: Acted as a drop-in Redis replacement with full protocol compatibility\u2014no changes needed in application code or client libraries.\\n\\n3\ufe0f\u20e3 Moving to GoLang for Cost-Efficient Serving\\nJava services were memory-heavy\u2014so we rewrote core services in GoLang. The results?\\n\\n\u2705 Memory usage dropped by ~80%\\n\u2705 CPU utilization was significantly lower\\n\u2705 Faster, more efficient deployments\\n\\n#### Optimizing the Interaction Store\\nWe realized that we only need a user\u2019s interaction data in Redis when they open the app. So, we implemented a tiered storage approach:\\n\\n- \ud83d\udccc Cold Tier (ScyllaDB)\u2014Stores click, order, wishlist events\\n- \ud83d\udccc Hot Tier (Redis)\u2014Loads a user\u2019s past interactions only when they open the app\\n\\nSmart Offloading: We introduced an inactivity tracker to detect when a user session ends. At that point, Redis data was flushed back to Scylla, reducing unnecessary writes.\\n\\n![InteractionStore](./interaction-str.png)\\n#### Results\\n\\n- Online Feature Store hit 1M QPS for the first time during the 2023 Mega Blockbuster Sale\u2014without breaking a sweat\\n- Infra costs for Online Feature Store and Interaction Store dropped by ~60%\\n\\n#### The Catch: Our ML Hosting Hit a Hard Limit\\nWhile planning for 2023 MBS, we ran into a critical scalability bottleneck:\\n\\n- \u274c Insufficient compute availability in our region for ML instances\\n- \u274c Couldn\u2019t provision enough nodes to handle real-time inference at scale\\n\\nThis forced us to rethink where and how we hosted our models. The existing setup was great for prototyping\u2014but it wasn\u2019t built to handle the bursty, high-QPS demands of real-world production workloads.\\n\\n### Conclusion: From Firefighting to Future-Proofing\\nWhat started as an ambitious experiment turned into a real-time ML infrastructure that powered millions of requests per second. We battled scaling pains, rethought feature retrieval with Inferflow, and rebuilt our infra stack for efficiency\u2014driving down costs while improving experimentation velocity.\\nBut new challenges emerged. Our infrastructure could now handle scale, but our ML model hosting setup hit a hard limit. With compute availability bottlenecks threatening real-time inference, we faced a critical decision: how do we make model serving as scalable and cost-efficient as the rest of our stack? That\u2019s the next piece of the puzzle\u2014and the story of Part 3."},{"id":"post-one","metadata":{"permalink":"/BharatMLStack/blog/post-one","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-one/index.md","source":"@site/blog/bharatmlstack-history/post-one/index.md","title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","description":"BharatMLStack","date":"2022-11-15T00:00:00.000Z","tags":[{"inline":true,"label":"online-feature-store","permalink":"/BharatMLStack/blog/tags/online-feature-store"},{"inline":true,"label":"interaction-store","permalink":"/BharatMLStack/blog/tags/interaction-store"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"}],"readingTime":10.25,"hasTruncateMarker":false,"authors":[{"name":"Adarsha Das","title":"Senior Architect @ Meesho","url":"https://github.com/a0d00kc","imageURL":"https://github.com/a0d00kc.png","key":"adarsha","page":null},{"name":"Aditya Kumar","title":"Lead Software Engineer @ Meesho","url":"https://github.com/Adit2607","imageURL":"https://github.com/Adit2607.png","key":"aditya","page":null},{"name":"Bhawani Singh","title":"Architect @ Meesho","url":"https://github.com/singh-bhawani","imageURL":"https://github.com/singh-bhawani.png","key":"bhawani","page":null},{"name":"Jigar Dave","title":"Lead Software Engineer @ Meesho","url":"https://github.com/jigarpatel26","imageURL":"https://github.com/jigarpatel26.png","key":"jigar","page":null}],"frontMatter":{"slug":"post-one","title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","authors":["adarsha","aditya","bhawani","jigar"],"date":"2022-11-15T00:00:00.000Z","tags":["online-feature-store","interaction-store","mlplatform","meesho"]},"unlisted":false,"prevItem":{"title":"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)","permalink":"/BharatMLStack/blog/post-two"}},"content":"![BharatMLStack](./bms.png)\\n## The Genesis: How a Friday Night Roast Sparked Meesho\u2019s ML Platform\\n\\nIt all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting\u2014until one remark hit a little too close to home:\\n\\n*\\"Why are we still crunching data for Monthly Active Users (MAU) when the next day it\u2019s all about Daily Active Users (DAU)?\\"*\\n\\nThe laughter died down, and the question lingered. When we regrouped on Monday\u2014clear-headed and slightly reflective\u2014we decided to dig into the numbers. What they discovered was quite revealing: a large portion of compute resources wasn\u2019t being put to good use.\\nMuch of the system\u2019s effort was spent supporting users who weren\u2019t actively engaging, and even for new users, the experience wasn\u2019t optimized to make a meaningful impact.\\n\\nAt the same time, Meesho had just launched a company-wide initiative to reduce costs\u2014and every team had to contribute. This realization sparked the journey that would eventually lead to the **Meesho ML Platform**, known today as **BharatMLStack**.\\n\\n![Alt Text](./old-batch-arch.png)\\n\\nBefore the ML Platform, our recommendation and ranking pipelines followed a batch processing approach:\\n- **Data Ingestion**: The Data Platform team executed ETL jobs to ingest raw user data\u2014including user profiles, interaction logs, and product impressions\u2014into designated S3 buckets.\\n- **Layer 1**: Embedding Generation: On the Data Science side, Spark jobs pulled data from multiple S3 sources, cleaned and preprocessed it, and applied matrix factorization to generate user and item embeddings. The processed data and embeddings were then stored back in S3 in a structured format.\\n- **Layer 2**: Candidate Generation (CG): In this stage, Spark jobs leveraged embeddings and historical interaction data to generate candidate recommendations for users. These candidate lists were subsequently written to S3.\\n- **Layer 3**: Ranking and Merging \u2013 A final round of processing ranked the generated candidates using ML models, combined different candidate lists, and stored the final ranked recommendations in a caching system.\\n- **Serving**: A microservice retrieved ranked recommendations from an in-memory data store via exposed APIs, delivering personalized listings across key surfaces such as \\"For You\\" and Category Landing Pages (CLP).\\n\\nThis approach held up well\u2014until Meesho started seeing a significant surge in traffic.\\n\\n## The Turning Point: From Batch to Real-Time\\n\\nAt this time, the team was iterating on new **Ranker models**, and real-time inference seemed like the next logical step. But Rankers needed **real-time feature retrieval**, which meant an **online feature store** had to be built first.\\n\\nExploring open-source options led to **cost vs. performance trade-offs**, but Meesho\u2019s surging traffic meant that **latency and stability were non-negotiable**. After multiple debates and stakeholder discussions, a bold decision was made:\\n\\n*We would build our own feature store.*\\n\\nMeanwhile, efforts began to bring **Candidate Generators (CGs)** to real-time. The challenge? **Storing and retrieving user interactions quickly enough** to power real-time recommendations.\\n\\nAs the team dove deeper, a new roadblock emerged: \\nOur ML jobs were orchestrated using **Airflow DAGs**, giving data scientists flexibility in experimentation. But transitioning to real-time execution threatened this agility. Every change would now require backend engineering support, **slowing down iteration cycles**.\\n\\nThat\u2019s when the idea struck: \\nWe needed a **framework for real-time DAG execution**\u2014one that preserved the same flexibility as Airflow but worked for **streaming data**.\\n\\nThis moment shaped the **next phase of our journey**.\\n\\n## First Generation Design\\n\\n![Alt Text](./first-gen-arch.png)\\n\\n# Laying the Groundwork: The First-Gen ML Platform\\n\\nTo solve these challenges, the team built three foundational components:\\n\\n\\n### 1. IOP Framework: A Real-Time DAG Executor\\n\\n- **Reusable Nodes**: Each DAG node (e.g., an invocation to a CG service, a ranker, or a filter) had to be implemented only once. After that, it could be reused across any workflow by referencing it in config.\\n- **Config-driven Dynamic Graphs**: Execution graphs were defined as adjacency lists stored in **ZooKeeper**, allowing teams to modify the sequence or structure of operations without touching application code.\\n- **Plug-and-play CGs**: The Candidate Generator interface was preserved, so a single CG node could call any CG service by passing `cg_name` in the request. This drastically reduced the code surface area and improved maintainability.\\n- **Production-Grade DAGs**: DAGs were designed to execute in **low-latency real-time environments**, with support for **parallel execution, retries, and branching**.\\n\\n[More about IOP DAG](https://www.meesho.io/blog/rebuilding-meeshos-ranking-platform)\\n\\n\\n### 2. Online Feature Store - 0th Version\\n\\n- Used **Cassandra** and **Redis** for low-latency feature serving.\\n- Maintained feature consistency using **Feature Groups** with TTL-based expiry.\\n- A hybrid schema was used: feature keys stored in **ZooKeeper**, data stored in **compact arrays**.\\n\\n\\n### 3. Interaction Store - 0th Version\\n\\n- Captured real-time user interactions like clicks, orders, and add-to-cart events.\\n- Stored event data in **Redis ZSETs (sorted sets)** to enable fast lookups for recommendation engines.\\n- Provided an API to fetch a user\'s **last _k_ interactions** or **interactions within a time window**.\\n\\n\\nWith these components in place, **real-time ML at Meesho became a reality**.\\n\\nThis was just the beginning.\\n\\n## Building the Online Feature Store - 0th Version\\n\\n![Alt text](./online-feature-store-v0.png)\\n\\n### Choosing the Right Tech Stack\\n\\nWe spent considerable time evaluating various databases, caches, and communication protocols for our **online feature store**. After carefully weighing **cost, latency, throughput**, and **operational stability**, we settled on a combination of:\\n\\n- **Cassandra** and **Redis** for storage\\n- **gRPC + Proto3** as our communication layer\\n\\n\\n### Streamlining the Data Flow\\n\\nTo keep things simple in the initial version:\\n\\n- **Feature engineering jobs** wrote raw outputs to an **S3 bucket**\\n- A **daily feature push job**:\\n - Read from S3\\n - Grouped related features into **Feature Groups** (ensuring consistency)\\n - Pushed them to **Kafka**\\n\\nFor features requiring frequent updates:\\n\\n- **Ad-hoc jobs** computed features in higher frequency\\n- These jobs pushed to both **Kafka** and **S3** (S3 preserved historical data for future model training)\\n\\n\\n## The Challenges: Data Format and Storage\\n\\nOne of the most critical design challenges was how to store feature data **efficiently and consistently**, especially in databases like **Cassandra** and **Redis**, which come with unique storage constraints.\\n\\nWe had to solve for three key requirements:\\n\\n- ### Feature Consistency\\n When a feature group contains features like `order_count_1h` and `click_count_1h`, both must reflect the **same time window**. Inconsistent updates would lead to **unreliable model predictions**.\\n\\n- ### TTL Granularity\\n Each feature group required an **expiry timestamp**, so that **all features within it expired together**\u2014preserving consistency during reads.\\n\\n- ### Extensibility Across Databases\\n We anticipated that infra needs would evolve. To future-proof our system, the data format was designed to be **decoupled from DB-specific layouts**, enabling portability to systems like **ScyllaDB**, **DynamoDB**, **HBase**, or **BigTable**.\\n\\n\\n---\\n\\n## Overcoming Technical Constraints\\nAt the time, we were using Cassandra, which not only imposed a soft limit of 75 columns per row, but also exhibited significant performance degradation as the number of columns increased further, particularly in memory constrained machines. Wide rows caused high memory usage during reads, unpredictable latencies due to heavy deserialization overhead, and inefficiencies during compactions and repairs. This ruled out the naive \\"one column per feature\\" approach. We needed a format that was compact, minimized the number of columns, and remained efficient and portable across different storage systems.\\n\\n## The Solution: Schema Separation\\n\\nWe introduced the concept of Feature Groups\u2014logical groupings of features that must remain consistent with one another.\\nTo represent these groups efficiently, we adopted a layered storage approach:\\n\\n- **Feature Labels (Keys)** were stored in ZooKeeper, serving as the schema.\\n- **Feature Values** were stored as a comma-separated string array in Cassandra or Redis.\\n- **Expiry Timestamp and Schema Version** were appended using a semi-colon delimiter at the end of the string.\\n\\nExample:\\n\\n```bash\\nfeature_1_value,feature_2_value,feature_3_value;expiry_ts\\n```\\n\\nThis format allowed:\\n- Consistent writes and reads at the group level\\n- Easy parsing of feature values using the schema lookup from ZooKeeper\\n- Efficient storage with minimal DB column usage\\n- Support for per-group TTLs and schema evolution\\n\\n## Tracking Changes in Feature Groups\\nFeature groups don\u2019t stay static. As models evolve, features get added, renamed, or removed. But schema changes often go live before the data is ready\u2014and stopping ingestion just to wait for everything to align isn\'t feasible.\\n\\n### Common Real-World Scenarios:\\n- A new feature is added to the schema, but ingestion jobs still use the older schema version.\\n- Ongoing writes don\u2019t include the newly added feature, and stopping ingestion would break freshness for existing features.\\n- During serving, models request a mix of old and new features, depending on rollout stages.\\n\\n## The Solution: Schema Versioning\\nWe solved this with versioned feature group schemas, which unlocked several capabilities:\\n- ### Backward Compatibility\\n Older ingestion jobs can continue writing using older schema versions. During reads, the system uses the schema version embedded in the value to interpret the data correctly.\\n- ### Partial Availability Handling \\n During inference, if some features in the request aren\u2019t available (due to rollout delays or missing data), the system serves default values, ensuring the inference call doesn\u2019t fail.\\n- ### Safe Writes Without Pipeline Pauses\\n With schema versioning, we no longer had to stop ingestion pipelines for schema updates. Writes using previous versions can continue safely, and downstream consumers evolve independently.\\nThis design gave us the flexibility to move fast without breaking things\u2014preserving data quality, enabling experimentation, and ensuring reliability at scale.\\n\\n![Alt Text](./schema.png)\\n\\n## Interaction Store - 0th Version\\n\\n![Alt Text](./interaction-store-v0.png)\\n\\nTo power real-time Candidate Generators (CGs), we needed fast access to user behavior signals\u2014like what a user recently clicked, ordered, or added to their cart. These interactions form the basis for many real-time recommendations, such as **Similar Products**, **People Also Viewed**, or **Recently Ordered Again**.\\nFor the **0th version** of the Interaction Store, we focused on a design that was **simple, fast, and reliable** \u2014 optimized for high-throughput ingestion and low-latency lookups.\\n\\n## Event Ingestion\\nWe instrumented our backend services to emit key user interaction events to Kafka in real time. These included:\\n- Click\\n- Order\\n- Add to Cart\\n- Wishlist\\n- Share\\n\\nEach event carried essential metadata:\\n- userId \u2014 uniquely identifies the user\\n- productId \u2014 the item being interacted with\\n- timestamp \u2014 the moment the interaction occurred\\n\\nThis decoupled the interaction logging from storage, allowing ingestion and consumption to scale independently.\\n\\n## Storage Design\\nTo store these events, we built Kafka consumers that processed the incoming streams and wrote the data into Redis, using sorted sets (ZSETs) as the primary data structure.\\n\\n### Why Redis?\\nRedis gave us:\\n- **Low-latency** reads and writes\\n- **Time-ordered data** using ZSETs (via score = timestamp)\\n- **Native TTL support**, if needed in later versions\\n- **In-memory performance** \u2014ideal for real-time CGs\\n\\n### Storage Structure\\nEach user\u2019s interactions were stored using a composite key format, uniquely identifying the user and interaction type. This structure allowed efficient organization and quick retrieval of recent activity for recommendation generation:\\n\\n```bash\\nuserId_eventType \u2192 ZSET[...(pid, ts)...]\\n```\\n\\nWithin each ZSET:\\n\\n- The **timestamp** served as the score, maintaining temporal order\\n- The **productId** (optionally with metadata) was the **value**\\n\\nThis allowed us to efficiently retrieve the interactions with HTTP-based API server with two query modes:\\n- Fetch the **last k interactions** of a specific type for a given user with `ZREVRANGE(userId_eventType, count)`\\n- Retrieve **all interactions within a time range** (e.g., last 24 hours) with `ZREVRANGEBYSCORE(userId_eventType, timeRange)`\\n\\n### Built-in Guardrails\\nSince Redis was the sole store, we implemented High Availability (HA) to prevent data loss. To optimize memory usage, we also enforced size limits per event type\u2014only storing the last k interactions per user, with older entries getting truncated.\\n\\n## Conclusion: Laying the Foundation for Real-Time ML\\n\\nIn this first phase, we tackled the **fundamentals**\u2014shifting from batch-based recommendations to a **real-time Recommendation** using ML platform that could keep up with Meesho\u2019s growth.\\n\\nWith the **IOP Framework**, **Online Feature Store**, and **Interaction Store**, we built the core infrastructure to support real-time personalization at scale. These wins have already unlocked: \\n- \u2705 Faster, more dynamic recommendations for millions of users. \\n- \u2705 Better infrastructure efficiency, reducing wasted compute power. \\n- \u2705 A flexible, modular system that allows for further experimentation.\\n\\nBut this is just the beginning. While we\'ve solved key challenges, **certain roadblocks remain** \u2014from optimizing **cost-performance trade-offs** to **seamlessly evolving schemas**.\\n\\n\\nThis foundational work laid the path for a reliable and scalable **real-time feature serving layer**."}]}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/6479fb86.d4723af3.js b/docs/assets/js/6479fb86.d4723af3.js deleted file mode 100644 index f3817767..00000000 --- a/docs/assets/js/6479fb86.d4723af3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5579],{3751:e=>{e.exports=JSON.parse('{"archive":{"blogPosts":[{"id":"post-one","metadata":{"permalink":"/BharatMLStack/blog/post-one","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-one/index.md","source":"@site/blog/bharatmlstack-history/post-one/index.md","title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","description":"BharatMLStack","date":"2022-11-15T00:00:00.000Z","tags":[{"inline":true,"label":"online-feature-store","permalink":"/BharatMLStack/blog/tags/online-feature-store"},{"inline":true,"label":"interaction-store","permalink":"/BharatMLStack/blog/tags/interaction-store"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"}],"readingTime":10.25,"hasTruncateMarker":false,"authors":[{"name":"Adarsha Das","title":"Senior Architect @ Meesho","url":"https://github.com/a0d00kc","imageURL":"https://github.com/a0d00kc.png","key":"adarsha","page":null},{"name":"Aditya Kumar","title":"SDE-III @ Meesho","url":"https://github.com/Adit2607","imageURL":"https://github.com/Adit2607.png","key":"aditya","page":null},{"name":"Bhawani Singh","title":"SDE-IV @ Meesho","url":"https://github.com/singh-bhawani","imageURL":"https://github.com/singh-bhawani.png","key":"bhawani","page":null},{"name":"Jigar Dave","title":"SDE-IV @ Meesho","url":"https://github.com/jigarpatel26","imageURL":"https://github.com/jigarpatel26.png","key":"jigar","page":null}],"frontMatter":{"slug":"post-one","title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","authors":["adarsha","aditya","bhawani","jigar"],"date":"2022-11-15T00:00:00.000Z","tags":["online-feature-store","interaction-store","mlplatform","meesho"]},"unlisted":false},"content":"![BharatMLStack](./bharatmlstack.png)\\n## The Genesis: How a Friday Night Roast Sparked Meesho\u2019s ML Platform\\n\\nIt all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting\u2014until one remark hit a little too close to home:\\n\\n*\\"Why are we still crunching data for Monthly Active Users (MAU) when the next day it\u2019s all about Daily Active Users (DAU)?\\"*\\n\\nThe laughter died down, and the question lingered. When we regrouped on Monday\u2014clear-headed and slightly reflective\u2014we decided to dig into the numbers. What they discovered was quite revealing: a large portion of compute resources wasn\u2019t being put to good use.\\nMuch of the system\u2019s effort was spent supporting users who weren\u2019t actively engaging, and even for new users, the experience wasn\u2019t optimized to make a meaningful impact.\\n\\nAt the same time, Meesho had just launched a company-wide initiative to reduce costs\u2014and every team had to contribute. This realization sparked the journey that would eventually lead to the **Meesho ML Platform**, known today as **BharatMLStack**.\\n\\n![Alt Text](./old-batch-arch.png)\\n\\nBefore the ML Platform, our recommendation and ranking pipelines followed a batch processing approach:\\n- **Data Ingestion**: The Data Platform team executed ETL jobs to ingest raw user data\u2014including user profiles, interaction logs, and product impressions\u2014into designated S3 buckets.\\n- **Layer 1**: Embedding Generation: On the Data Science side, Spark jobs pulled data from multiple S3 sources, cleaned and preprocessed it, and applied matrix factorization to generate user and item embeddings. The processed data and embeddings were then stored back in S3 in a structured format.\\n- **Layer 2**: Candidate Generation (CG): In this stage, Spark jobs leveraged embeddings and historical interaction data to generate candidate recommendations for users. These candidate lists were subsequently written to S3.\\n- **Layer 3**: Ranking and Merging \u2013 A final round of processing ranked the generated candidates using ML models, combined different candidate lists, and stored the final ranked recommendations in a caching system.\\n- **Serving**: A microservice retrieved ranked recommendations from an in-memory data store via exposed APIs, delivering personalized listings across key surfaces such as \\"For You\\" and Category Landing Pages (CLP).\\n\\nThis approach held up well\u2014until Meesho started seeing a significant surge in traffic.\\n\\n## The Turning Point: From Batch to Real-Time\\n\\nAt this time, the team was iterating on new **Ranker models**, and real-time inference seemed like the next logical step. But Rankers needed **real-time feature retrieval**, which meant an **online feature store** had to be built first.\\n\\nExploring open-source options led to **cost vs. performance trade-offs**, but Meesho\u2019s surging traffic meant that **latency and stability were non-negotiable**. After multiple debates and stakeholder discussions, a bold decision was made:\\n\\n*We would build our own feature store.*\\n\\nMeanwhile, efforts began to bring **Candidate Generators (CGs)** to real-time. The challenge? **Storing and retrieving user interactions quickly enough** to power real-time recommendations.\\n\\nAs the team dove deeper, a new roadblock emerged: \\nOur ML jobs were orchestrated using **Airflow DAGs**, giving data scientists flexibility in experimentation. But transitioning to real-time execution threatened this agility. Every change would now require backend engineering support, **slowing down iteration cycles**.\\n\\nThat\u2019s when the idea struck: \\nWe needed a **framework for real-time DAG execution**\u2014one that preserved the same flexibility as Airflow but worked for **streaming data**.\\n\\nThis moment shaped the **next phase of our journey**.\\n\\n## First Generation Design\\n\\n![Alt Text](./first-gen-arch.png)\\n\\n# Laying the Groundwork: The First-Gen ML Platform\\n\\nTo solve these challenges, the team built three foundational components:\\n\\n\\n### 1. IOP Framework: A Real-Time DAG Executor\\n\\n- **Reusable Nodes**: Each DAG node (e.g., an invocation to a CG service, a ranker, or a filter) had to be implemented only once. After that, it could be reused across any workflow by referencing it in config.\\n- **Config-driven Dynamic Graphs**: Execution graphs were defined as adjacency lists stored in **ZooKeeper**, allowing teams to modify the sequence or structure of operations without touching application code.\\n- **Plug-and-play CGs**: The Candidate Generator interface was preserved, so a single CG node could call any CG service by passing `cg_name` in the request. This drastically reduced the code surface area and improved maintainability.\\n- **Production-Grade DAGs**: DAGs were designed to execute in **low-latency real-time environments**, with support for **parallel execution, retries, and branching**.\\n\\n[More about IOP DAG](https://www.meesho.io/blog/rebuilding-meeshos-ranking-platform)\\n\\n\\n### 2. Online Feature Store - 0th Version\\n\\n- Used **Cassandra** and **Redis** for low-latency feature serving.\\n- Maintained feature consistency using **Feature Groups** with TTL-based expiry.\\n- A hybrid schema was used: feature keys stored in **ZooKeeper**, data stored in **compact arrays**.\\n\\n\\n### 3. Interaction Store - 0th Version\\n\\n- Captured real-time user interactions like clicks, orders, and add-to-cart events.\\n- Stored event data in **Redis ZSETs (sorted sets)** to enable fast lookups for recommendation engines.\\n- Provided an API to fetch a user\'s **last _k_ interactions** or **interactions within a time window**.\\n\\n\\nWith these components in place, **real-time ML at Meesho became a reality**.\\n\\nThis was just the beginning.\\n\\n## Building the Online Feature Store - 0th Version\\n\\n![Alt text](./online-feature-store-v0.png)\\n\\n### Choosing the Right Tech Stack\\n\\nWe spent considerable time evaluating various databases, caches, and communication protocols for our **online feature store**. After carefully weighing **cost, latency, throughput**, and **operational stability**, we settled on a combination of:\\n\\n- **Cassandra** and **Redis** for storage\\n- **gRPC + Proto3** as our communication layer\\n\\n\\n### Streamlining the Data Flow\\n\\nTo keep things simple in the initial version:\\n\\n- **Feature engineering jobs** wrote raw outputs to an **S3 bucket**\\n- A **daily feature push job**:\\n - Read from S3\\n - Grouped related features into **Feature Groups** (ensuring consistency)\\n - Pushed them to **Kafka**\\n\\nFor features requiring frequent updates:\\n\\n- **Ad-hoc jobs** computed features in higher frequency\\n- These jobs pushed to both **Kafka** and **S3** (S3 preserved historical data for future model training)\\n\\n\\n## The Challenges: Data Format and Storage\\n\\nOne of the most critical design challenges was how to store feature data **efficiently and consistently**, especially in databases like **Cassandra** and **Redis**, which come with unique storage constraints.\\n\\nWe had to solve for three key requirements:\\n\\n- ### Feature Consistency\\n When a feature group contains features like `order_count_1h` and `click_count_1h`, both must reflect the **same time window**. Inconsistent updates would lead to **unreliable model predictions**.\\n\\n- ### TTL Granularity\\n Each feature group required an **expiry timestamp**, so that **all features within it expired together**\u2014preserving consistency during reads.\\n\\n- ### Extensibility Across Databases\\n We anticipated that infra needs would evolve. To future-proof our system, the data format was designed to be **decoupled from DB-specific layouts**, enabling portability to systems like **ScyllaDB**, **DynamoDB**, **HBase**, or **BigTable**.\\n\\n\\n---\\n\\n## Overcoming Technical Constraints\\nAt the time, we were using Cassandra, which not only imposed a soft limit of 75 columns per row, but also exhibited significant performance degradation as the number of columns increased further, particularly in memory constrained machines. Wide rows caused high memory usage during reads, unpredictable latencies due to heavy deserialization overhead, and inefficiencies during compactions and repairs. This ruled out the naive \\"one column per feature\\" approach. We needed a format that was compact, minimized the number of columns, and remained efficient and portable across different storage systems.\\n\\n## The Solution: Schema Separation\\n\\nWe introduced the concept of Feature Groups\u2014logical groupings of features that must remain consistent with one another.\\nTo represent these groups efficiently, we adopted a layered storage approach:\\n\\n- **Feature Labels (Keys)** were stored in ZooKeeper, serving as the schema.\\n- **Feature Values** were stored as a comma-separated string array in Cassandra or Redis.\\n- **Expiry Timestamp and Schema Version** were appended using a semi-colon delimiter at the end of the string.\\n\\nExample:\\n\\n```bash\\nfeature_1_value,feature_2_value,feature_3_value;expiry_ts\\n```\\n\\nThis format allowed:\\n- Consistent writes and reads at the group level\\n- Easy parsing of feature values using the schema lookup from ZooKeeper\\n- Efficient storage with minimal DB column usage\\n- Support for per-group TTLs and schema evolution\\n\\n## Tracking Changes in Feature Groups\\nFeature groups don\u2019t stay static. As models evolve, features get added, renamed, or removed. But schema changes often go live before the data is ready\u2014and stopping ingestion just to wait for everything to align isn\'t feasible.\\n\\n### Common Real-World Scenarios:\\n- A new feature is added to the schema, but ingestion jobs still use the older schema version.\\n- Ongoing writes don\u2019t include the newly added feature, and stopping ingestion would break freshness for existing features.\\n- During serving, models request a mix of old and new features, depending on rollout stages.\\n\\n## The Solution: Schema Versioning\\nWe solved this with versioned feature group schemas, which unlocked several capabilities:\\n- ### Backward Compatibility\\n Older ingestion jobs can continue writing using older schema versions. During reads, the system uses the schema version embedded in the value to interpret the data correctly.\\n- ### Partial Availability Handling \\n During inference, if some features in the request aren\u2019t available (due to rollout delays or missing data), the system serves default values, ensuring the inference call doesn\u2019t fail.\\n- ### Safe Writes Without Pipeline Pauses\\n With schema versioning, we no longer had to stop ingestion pipelines for schema updates. Writes using previous versions can continue safely, and downstream consumers evolve independently.\\nThis design gave us the flexibility to move fast without breaking things\u2014preserving data quality, enabling experimentation, and ensuring reliability at scale.\\n\\n![Alt Text](./schema.png)\\n\\n## Interaction Store - 0th Version\\n\\n![Alt Text](./interaction-store-v0.png)\\n\\nTo power real-time Candidate Generators (CGs), we needed fast access to user behavior signals\u2014like what a user recently clicked, ordered, or added to their cart. These interactions form the basis for many real-time recommendations, such as **Similar Products**, **People Also Viewed**, or **Recently Ordered Again**.\\nFor the **0th version** of the Interaction Store, we focused on a design that was **simple, fast, and reliable** \u2014 optimized for high-throughput ingestion and low-latency lookups.\\n\\n## Event Ingestion\\nWe instrumented our backend services to emit key user interaction events to Kafka in real time. These included:\\n- Click\\n- Order\\n- Add to Cart\\n- Wishlist\\n- Share\\n\\nEach event carried essential metadata:\\n- userId \u2014 uniquely identifies the user\\n- productId \u2014 the item being interacted with\\n- timestamp \u2014 the moment the interaction occurred\\n\\nThis decoupled the interaction logging from storage, allowing ingestion and consumption to scale independently.\\n\\n## Storage Design\\nTo store these events, we built Kafka consumers that processed the incoming streams and wrote the data into Redis, using sorted sets (ZSETs) as the primary data structure.\\n\\n### Why Redis?\\nRedis gave us:\\n- **Low-latency** reads and writes\\n- **Time-ordered data** using ZSETs (via score = timestamp)\\n- **Native TTL support**, if needed in later versions\\n- **In-memory performance** \u2014ideal for real-time CGs\\n\\n### Storage Structure\\nEach user\u2019s interactions were stored using a composite key format, uniquely identifying the user and interaction type. This structure allowed efficient organization and quick retrieval of recent activity for recommendation generation:\\n\\n```bash\\nuserId_eventType \u2192 ZSET[...(pid, ts)...]\\n```\\n\\nWithin each ZSET:\\n\\n- The **timestamp** served as the score, maintaining temporal order\\n- The **productId** (optionally with metadata) was the **value**\\n\\nThis allowed us to efficiently retrieve the interactions with HTTP-based API server with two query modes:\\n- Fetch the **last k interactions** of a specific type for a given user with `ZREVRANGE(userId_eventType, count)`\\n- Retrieve **all interactions within a time range** (e.g., last 24 hours) with `ZREVRANGEBYSCORE(userId_eventType, timeRange)`\\n\\n### Built-in Guardrails\\nSince Redis was the sole store, we implemented High Availability (HA) to prevent data loss. To optimize memory usage, we also enforced size limits per event type\u2014only storing the last k interactions per user, with older entries getting truncated.\\n\\n## Conclusion: Laying the Foundation for Real-Time ML\\n\\nIn this first phase, we tackled the **fundamentals**\u2014shifting from batch-based recommendations to a **real-time Recommendation** using ML platform that could keep up with Meesho\u2019s growth.\\n\\nWith the **IOP Framework**, **Online Feature Store**, and **Interaction Store**, we built the core infrastructure to support real-time personalization at scale. These wins have already unlocked: \\n- \u2705 Faster, more dynamic recommendations for millions of users. \\n- \u2705 Better infrastructure efficiency, reducing wasted compute power. \\n- \u2705 A flexible, modular system that allows for further experimentation.\\n\\nBut this is just the beginning. While we\'ve solved key challenges, **certain roadblocks remain** \u2014from optimizing **cost-performance trade-offs** to **seamlessly evolving schemas**.\\n\\n\\nThis foundational work laid the path for a reliable and scalable **real-time feature serving layer**."}]}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/67d4782a.09ac845b.js b/docs/assets/js/67d4782a.09ac845b.js deleted file mode 100644 index 6a09823e..00000000 --- a/docs/assets/js/67d4782a.09ac845b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8588],{8453:(e,r,n)=>{n.d(r,{R:()=>t,x:()=>l});var s=n(6540);const o={},i=s.createContext(o);function t(e){const r=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function l(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),s.createElement(i.Provider,{value:r},e.children)}},8769:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>t,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"online-feature-store/v1.0.0/benchmarks","title":"Benchmarks","description":"Summary","source":"@site/docs/online-feature-store/v1.0.0/benchmarks.md","sourceDirName":"online-feature-store/v1.0.0","slug":"/online-feature-store/v1.0.0/benchmarks","permalink":"/BharatMLStack/online-feature-store/v1.0.0/benchmarks","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/online-feature-store/v1.0.0/benchmarks.md","tags":[],"version":"current","sidebarPosition":3,"frontMatter":{"title":"Benchmarks","sidebar_position":3},"sidebar":"tutorialSidebar","previous":{"title":"Data Formats","permalink":"/BharatMLStack/online-feature-store/v1.0.0/data-formats"},"next":{"title":"Key Functionalities","permalink":"/BharatMLStack/online-feature-store/v1.0.0/functionalities"}}');var o=n(4848),i=n(8453);const t={title:"Benchmarks",sidebar_position:3},l="Serialization Performance Benchmarks",a={},c=[{value:"Summary",id:"summary",level:2},{value:"Test Methodology",id:"test-methodology",level:2},{value:"Environment",id:"environment",level:3},{value:"Test Data",id:"test-data",level:3},{value:"Performance Results",id:"performance-results",level:2},{value:"Serialization Speed (Lower is Better)",id:"serialization-speed-lower-is-better",level:3},{value:"Serialized Size (Lower is Better)",id:"serialized-size-lower-is-better",level:3},{value:"Memory Efficiency (Lower is Better)",id:"memory-efficiency-lower-is-better",level:3},{value:"Throughput (Higher is Better)",id:"throughput-higher-is-better",level:3},{value:"Detailed Analysis",id:"detailed-analysis",level:2},{value:"PSDB Advantages",id:"psdb-advantages",level:3},{value:"Protocol Buffers Analysis",id:"protocol-buffers-analysis",level:3},{value:"Apache Arrow Analysis",id:"apache-arrow-analysis",level:3},{value:"Scaling Characteristics",id:"scaling-characteristics",level:2},{value:"Small Datasets (100-1,000 features)",id:"small-datasets-100-1000-features",level:3},{value:"Large Datasets (10,000+ features)",id:"large-datasets-10000-features",level:3},{value:"Technical Implementation Notes",id:"technical-implementation-notes",level:2},{value:"PSDB Optimizations",id:"psdb-optimizations",level:3},{value:"Memory Layout Comparison",id:"memory-layout-comparison",level:3},{value:"Conclusion",id:"conclusion",level:2},{value:"PSDB: Best for Small-Medium Scale (\u22641,000 features)",id:"psdb-best-for-small-medium-scale-1000-features",level:3},{value:"Apache Arrow: Best for Large Scale (\u226510,000 features)",id:"apache-arrow-best-for-large-scale-10000-features",level:3},{value:"Protocol Buffers: Balanced Middle Ground",id:"protocol-buffers-balanced-middle-ground",level:3},{value:"Raw Benchmark Output [Uncompressed Data]",id:"raw-benchmark-output-uncompressed-data",level:2}];function d(e){const r={code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(r.header,{children:(0,o.jsx)(r.h1,{id:"serialization-performance-benchmarks",children:"Serialization Performance Benchmarks"})}),"\n",(0,o.jsx)(r.h2,{id:"summary",children:"Summary"}),"\n",(0,o.jsx)(r.p,{children:"This report presents comprehensive benchmark results comparing three serialization formats for the BharatML Online Feature Store:"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"PSDB (Permanent Storage Data Block)"})," - Our custom format"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Protocol Buffers v3"})," - Google's binary serialization"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Apache Arrow"})," - Columnar in-memory analytics format"]}),"\n"]}),"\n",(0,o.jsx)(r.p,{children:(0,o.jsx)(r.strong,{children:"Key Findings:"})}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:["\ud83c\udfc6 ",(0,o.jsx)(r.strong,{children:"PSDB excels at small-to-medium scales"})," (100-1,000 features)"]}),"\n",(0,o.jsxs)(r.li,{children:["\u26a1 ",(0,o.jsx)(r.strong,{children:"35% faster"})," than Proto3, but ",(0,o.jsx)(r.strong,{children:"67% slower"})," than Arrow (for 100k features)"]}),"\n",(0,o.jsxs)(r.li,{children:["\ud83d\udce6 ",(0,o.jsx)(r.strong,{children:"18% smaller"})," than Proto3, comparable to Arrow"]}),"\n",(0,o.jsxs)(r.li,{children:["\ud83e\udde0 ",(0,o.jsx)(r.strong,{children:"93% fewer allocations"})," than Arrow (4 vs 66 allocs/op)"]}),"\n"]}),"\n",(0,o.jsx)(r.h2,{id:"test-methodology",children:"Test Methodology"}),"\n",(0,o.jsx)(r.h3,{id:"environment",children:"Environment"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Platform"}),": macOS ARM64 (Apple Silicon)"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Go Version"}),": 1.22.12"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Test Date"}),": January 2025"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Compression"}),": Disabled for fair comparison (",(0,o.jsx)(r.code,{children:"compression.TypeNone"}),")"]}),"\n"]}),"\n",(0,o.jsx)(r.h3,{id:"test-data",children:"Test Data"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Data Type"}),": Int32 arrays"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Feature Group Sizes"}),": 100, 1,000, 10,000, 100,000 features"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Test Iterations"}),": Variable (Go benchmark auto-scaling)"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Pool Optimization"}),": PSDB uses object pooling for memory efficiency"]}),"\n"]}),"\n",(0,o.jsx)(r.h2,{id:"performance-results",children:"Performance Results"}),"\n",(0,o.jsx)(r.h3,{id:"serialization-speed-lower-is-better",children:"Serialization Speed (Lower is Better)"}),"\n",(0,o.jsxs)(r.table,{children:[(0,o.jsx)(r.thead,{children:(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.th,{children:"Feature Count"}),(0,o.jsx)(r.th,{children:"PSDB (ns/op)"}),(0,o.jsx)(r.th,{children:"Proto3 (ns/op)"}),(0,o.jsx)(r.th,{children:"Arrow (ns/op)"}),(0,o.jsx)(r.th,{children:"PSDB vs Proto3"}),(0,o.jsx)(r.th,{children:"PSDB vs Arrow"})]})}),(0,o.jsxs)(r.tbody,{children:[(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"100"}),(0,o.jsx)(r.td,{children:"625"}),(0,o.jsx)(r.td,{children:"696"}),(0,o.jsx)(r.td,{children:"3,831"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"10% faster"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"84% faster"})})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"1,000"}),(0,o.jsx)(r.td,{children:"4,056"}),(0,o.jsx)(r.td,{children:"6,004"}),(0,o.jsx)(r.td,{children:"5,191"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"32% faster"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"22% faster"})})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"10,000"}),(0,o.jsx)(r.td,{children:"37,357"}),(0,o.jsx)(r.td,{children:"57,674"}),(0,o.jsx)(r.td,{children:"23,173"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"35% faster"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"38% slower"})})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"100,000"}),(0,o.jsx)(r.td,{children:"359,932"}),(0,o.jsx)(r.td,{children:"556,541"}),(0,o.jsx)(r.td,{children:"118,489"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"35% faster"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"67% slower"})})]})]})]}),"\n",(0,o.jsx)(r.h3,{id:"serialized-size-lower-is-better",children:"Serialized Size (Lower is Better)"}),"\n",(0,o.jsxs)(r.table,{children:[(0,o.jsx)(r.thead,{children:(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.th,{children:"Feature Count"}),(0,o.jsx)(r.th,{children:"Raw Size (bytes)"}),(0,o.jsx)(r.th,{children:"PSDB (bytes)"}),(0,o.jsx)(r.th,{children:"Proto3 (bytes)"}),(0,o.jsx)(r.th,{children:"Arrow (bytes)"}),(0,o.jsx)(r.th,{children:"PSDB Ratio"}),(0,o.jsx)(r.th,{children:"Proto3 Ratio"}),(0,o.jsx)(r.th,{children:"Arrow Ratio"})]})}),(0,o.jsxs)(r.tbody,{children:[(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"100"}),(0,o.jsx)(r.td,{children:"400"}),(0,o.jsx)(r.td,{children:"409"}),(0,o.jsx)(r.td,{children:"490"}),(0,o.jsx)(r.td,{children:"680"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"102.2%"})}),(0,o.jsx)(r.td,{children:"122.5%"}),(0,o.jsx)(r.td,{children:"170.0%"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"1,000"}),(0,o.jsx)(r.td,{children:"4,000"}),(0,o.jsx)(r.td,{children:"4,009"}),(0,o.jsx)(r.td,{children:"4,881"}),(0,o.jsx)(r.td,{children:"4,280"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"100.2%"})}),(0,o.jsx)(r.td,{children:"122.0%"}),(0,o.jsx)(r.td,{children:"107.0%"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"10,000"}),(0,o.jsx)(r.td,{children:"40,000"}),(0,o.jsx)(r.td,{children:"40,009"}),(0,o.jsx)(r.td,{children:"48,717"}),(0,o.jsx)(r.td,{children:"40,280"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"100.0%"})}),(0,o.jsx)(r.td,{children:"121.8%"}),(0,o.jsx)(r.td,{children:"100.7%"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"100,000"}),(0,o.jsx)(r.td,{children:"400,000"}),(0,o.jsx)(r.td,{children:"400,009"}),(0,o.jsx)(r.td,{children:"487,225"}),(0,o.jsx)(r.td,{children:"400,280"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"100.0%"})}),(0,o.jsx)(r.td,{children:"121.8%"}),(0,o.jsx)(r.td,{children:"100.1%"})]})]})]}),"\n",(0,o.jsx)(r.h3,{id:"memory-efficiency-lower-is-better",children:"Memory Efficiency (Lower is Better)"}),"\n",(0,o.jsxs)(r.table,{children:[(0,o.jsx)(r.thead,{children:(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.th,{children:"Feature Count"}),(0,o.jsx)(r.th,{children:"PSDB (B/op)"}),(0,o.jsx)(r.th,{children:"Proto3 (B/op)"}),(0,o.jsx)(r.th,{children:"Arrow (B/op)"}),(0,o.jsx)(r.th,{children:"PSDB (allocs/op)"}),(0,o.jsx)(r.th,{children:"Proto3 (allocs/op)"}),(0,o.jsx)(r.th,{children:"Arrow (allocs/op)"})]})}),(0,o.jsxs)(r.tbody,{children:[(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"100"}),(0,o.jsx)(r.td,{children:"461"}),(0,o.jsx)(r.td,{children:"768"}),(0,o.jsx)(r.td,{children:"7,032"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"4"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"2"})}),(0,o.jsx)(r.td,{children:"66"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"1,000"}),(0,o.jsx)(r.td,{children:"4,143"}),(0,o.jsx)(r.td,{children:"5,632"}),(0,o.jsx)(r.td,{children:"15,544"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"4"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"2"})}),(0,o.jsx)(r.td,{children:"66"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"10,000"}),(0,o.jsx)(r.td,{children:"41,029"}),(0,o.jsx)(r.td,{children:"49,408"}),(0,o.jsx)(r.td,{children:"122,617"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"4"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"2"})}),(0,o.jsx)(r.td,{children:"66"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"100,000"}),(0,o.jsx)(r.td,{children:"401,814"}),(0,o.jsx)(r.td,{children:"491,776"}),(0,o.jsx)(r.td,{children:"957,948"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"4"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"2"})}),(0,o.jsx)(r.td,{children:"66"})]})]})]}),"\n",(0,o.jsx)(r.h3,{id:"throughput-higher-is-better",children:"Throughput (Higher is Better)"}),"\n",(0,o.jsxs)(r.table,{children:[(0,o.jsx)(r.thead,{children:(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.th,{children:"Format"}),(0,o.jsx)(r.th,{children:"Throughput (MB/s)"}),(0,o.jsx)(r.th,{children:"Relative Performance"})]})}),(0,o.jsxs)(r.tbody,{children:[(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"PSDB"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"975.31"})}),(0,o.jsx)(r.td,{children:"Baseline (100%)"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"Proto3"}),(0,o.jsx)(r.td,{children:"666.12"}),(0,o.jsx)(r.td,{children:"68% of PSDB"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"Arrow"}),(0,o.jsx)(r.td,{children:"768.25"}),(0,o.jsx)(r.td,{children:"79% of PSDB"})]})]})]}),"\n",(0,o.jsx)(r.h2,{id:"detailed-analysis",children:"Detailed Analysis"}),"\n",(0,o.jsx)(r.h3,{id:"psdb-advantages",children:"PSDB Advantages"}),"\n",(0,o.jsxs)(r.ol,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Minimal Overhead"}),": Only 9-byte header + raw data"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Optimal Packing"}),": No padding or metadata bloat"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Memory Pooling"}),": Reuses objects to minimize allocations"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Native Optimization"}),": Designed specifically for feature store use cases"]}),"\n"]}),"\n",(0,o.jsx)(r.h3,{id:"protocol-buffers-analysis",children:"Protocol Buffers Analysis"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Consistent Overhead"}),": ~22% size penalty across all scales"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Moderate Speed"}),": Reasonable serialization performance"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Low Allocations"}),": Only 2 allocations per operation"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Varint Encoding"}),": Efficient for smaller integers"]}),"\n"]}),"\n",(0,o.jsx)(r.h3,{id:"apache-arrow-analysis",children:"Apache Arrow Analysis"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"High Setup Cost"}),": Complex object creation (66 allocations)"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Good Large-Scale"}),": Better relative performance with more data"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Size Efficient"}),": Approaches raw data size for large datasets"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Memory Intensive"}),": Significant memory overhead per operation"]}),"\n"]}),"\n",(0,o.jsx)(r.h2,{id:"scaling-characteristics",children:"Scaling Characteristics"}),"\n",(0,o.jsx)(r.h3,{id:"small-datasets-100-1000-features",children:"Small Datasets (100-1,000 features)"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"PSDB"}),": Consistent low overhead"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Proto3"}),": Moderate overhead, stable performance"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Arrow"}),": High setup cost dominates"]}),"\n"]}),"\n",(0,o.jsx)(r.h3,{id:"large-datasets-10000-features",children:"Large Datasets (10,000+ features)"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"PSDB"}),": Linear scaling, maintains efficiency"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Proto3"}),": Good scaling but with consistent 22% size penalty"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Arrow"}),": Better amortization of setup costs"]}),"\n"]}),"\n",(0,o.jsx)(r.h2,{id:"technical-implementation-notes",children:"Technical Implementation Notes"}),"\n",(0,o.jsx)(r.h3,{id:"psdb-optimizations",children:"PSDB Optimizations"}),"\n",(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{className:"language-go",children:"// Object pooling for zero allocations\nvar psdbPool = GetPSDBPool()\n\n// Direct buffer allocation\nheaderSize := PSDBLayout1LengthBytes // 9 bytes\ndataSize := len(data) * 4 // 4 bytes per int32\n\n// No compression for maximum speed\ncompressionType = compression.TypeNone\n"})}),"\n",(0,o.jsx)(r.h3,{id:"memory-layout-comparison",children:"Memory Layout Comparison"}),"\n",(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{children:"PSDB Layout: [9-byte header][raw data]\nProto3 Layout: [varint lengths][encoded data][padding]\nArrow Layout: [schema][metadata][buffers][padding]\n"})}),"\n",(0,o.jsx)(r.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,o.jsxs)(r.p,{children:[(0,o.jsx)(r.strong,{children:"The optimal format depends on your use case and scale"}),":"]}),"\n",(0,o.jsx)(r.h3,{id:"psdb-best-for-small-medium-scale-1000-features",children:(0,o.jsx)(r.strong,{children:"PSDB: Best for Small-Medium Scale (\u22641,000 features)"})}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Excellent speed"}),": Up to 83% faster than Arrow for small datasets"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Optimal size efficiency"}),": Closest to raw data size (100.0-102.2%)"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Memory efficiency"}),": Only 4 allocations per operation"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Low overhead"}),": Minimal 9-byte header"]}),"\n"]}),"\n",(0,o.jsx)(r.h3,{id:"apache-arrow-best-for-large-scale-10000-features",children:(0,o.jsx)(r.strong,{children:"Apache Arrow: Best for Large Scale (\u226510,000 features)"})}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Superior large-scale performance"}),": 67% faster than PSDB at 100k features"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Efficient scaling"}),": Better amortization of setup costs"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Size competitive"}),": Approaches raw data size for large datasets"]}),"\n"]}),"\n",(0,o.jsx)(r.h3,{id:"protocol-buffers-balanced-middle-ground",children:(0,o.jsx)(r.strong,{children:"Protocol Buffers: Balanced Middle Ground"})}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Consistent performance"}),": Moderate speed across all scales"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Standard tooling"}),": Wide ecosystem support"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Predictable overhead"}),": ~22% size penalty but stable"]}),"\n"]}),"\n",(0,o.jsxs)(r.p,{children:[(0,o.jsx)(r.strong,{children:"Recommendation"}),": For the Online Feature Store's typical use patterns with ",(0,o.jsx)(r.strong,{children:"sub-1,000 feature requests"}),", ",(0,o.jsx)(r.strong,{children:"PSDB is the optimal choice"})," for production deployments."]}),"\n",(0,o.jsx)(r.h2,{id:"raw-benchmark-output-uncompressed-data",children:"Raw Benchmark Output [Uncompressed Data]"}),"\n",(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{children:"goos: darwin\ngoarch: arm64\npkg: github.com/Meesho/BharatMLStack/online-feature-store/internal/data/blocks\nBenchmarkInt32SerializationPSDB/PSDB/Size-100-10 1940238 625.3 ns/op 409.0 bytes 461 B/op 4 allocs/op\nBenchmarkInt32SerializationPSDB/PSDB/Size-1000-10 288300 4056 ns/op 4009 bytes 4143 B/op 4 allocs/op\nBenchmarkInt32SerializationPSDB/PSDB/Size-10000-10 32144 37357 ns/op 40009 bytes 41032 B/op 4 allocs/op\nBenchmarkInt32SerializationPSDB/PSDB/Size-100000-10 3244 359932 ns/op 400009 bytes 401572 B/op 4 allocs/op\nBenchmarkInt32SerializationProto3/Proto3/Size-100-10 1703066 695.9 ns/op 486.0 bytes 768 B/op 2 allocs/op\nBenchmarkInt32SerializationProto3/Proto3/Size-1000-10 194142 6004 ns/op 4885 bytes 5632 B/op 2 allocs/op\nBenchmarkInt32SerializationProto3/Proto3/Size-10000-10 20937 57674 ns/op 48734 bytes 49408 B/op 2 allocs/op\nBenchmarkInt32SerializationProto3/Proto3/Size-100000-10 2085 556541 ns/op 487263 bytes 491776 B/op 2 allocs/op\nBenchmarkInt32SerializationArrow/Arrow/Size-100-10 302257 3831 ns/op 680.0 bytes 7032 B/op 66 allocs/op\nBenchmarkInt32SerializationArrow/Arrow/Size-1000-10 228718 5191 ns/op 4280 bytes 15544 B/op 66 allocs/op\nBenchmarkInt32SerializationArrow/Arrow/Size-10000-10 52482 23173 ns/op 40280 bytes 122617 B/op 66 allocs/op\nBenchmarkInt32SerializationArrow/Arrow/Size-100000-10 9765 120081 ns/op 400280 bytes 957948 B/op 66 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-100/PSDB-10 1919401 670.2 ns/op 409.0 bytes 461 B/op 4 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-100/Proto3-10 1733599 693.2 ns/op 490.0 bytes 768 B/op 2 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-100/Arrow-10 304066 3896 ns/op 680.0 bytes 7032 B/op 66 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-1000/PSDB-10 290784 4074 ns/op 4009 bytes 4143 B/op 4 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-1000/Proto3-10 196962 6034 ns/op 4882 bytes 5632 B/op 2 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-1000/Arrow-10 227908 5240 ns/op 4280 bytes 15544 B/op 66 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-10000/PSDB-10 31732 38064 ns/op 40009 bytes 41024 B/op 4 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-10000/Proto3-10 20827 57670 ns/op 48745 bytes 49408 B/op 2 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-10000/Arrow-10 52000 23557 ns/op 40280 bytes 122617 B/op 66 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-100000/PSDB-10 3268 363817 ns/op 400009 bytes 401575 B/op 4 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-100000/Proto3-10 2097 559621 ns/op 487247 bytes 491776 B/op 2 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-100000/Arrow-10 10000 118489 ns/op 400280 bytes 957947 B/op 66 allocs/op\nBenchmarkInt32SizeComparison/SizeOnly/Size-100-10 1000000000 0.0000223 ns/op 680.0 arrow_bytes 170.0 arrow_ratio_pct 490.0 proto3_bytes 122.5 proto3_ratio_pct 409.0 psdb_bytes 102.2 psdb_ratio_pct 400.0 raw_bytes\nBenchmarkInt32SizeComparison/SizeOnly/Size-1000-10 1000000000 0.0000379 ns/op 4280 arrow_bytes 107.0 arrow_ratio_pct 4881 proto3_bytes 122.0 proto3_ratio_pct 4009 psdb_bytes 100.2 psdb_ratio_pct 4000 raw_bytes\nBenchmarkInt32SizeComparison/SizeOnly/Size-10000-10 1000000000 0.0001182 ns/op 40280 arrow_bytes 100.7 arrow_ratio_pct 48717 proto3_bytes 121.8 proto3_ratio_pct 40009 psdb_bytes 100.0 psdb_ratio_pct 40000 raw_bytes\nBenchmarkInt32SizeComparison/SizeOnly/Size-100000-10 1000000000 0.001034 ns/op 400280 arrow_bytes 100.1 arrow_ratio_pct 487225 proto3_bytes 121.8 proto3_ratio_pct 400009 psdb_bytes 100.0 psdb_ratio_pct 400000 raw_bytes\nBenchmarkInt32MemoryEfficiency/Memory/Size-100/PSDB_Pooled-10 1926676 622.4 ns/op 461 B/op 4 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-100/Proto3-10 1713428 685.0 ns/op 768 B/op 2 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-100/Arrow-10 312584 4029 ns/op 7032 B/op 66 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-1000/PSDB_Pooled-10 290197 4189 ns/op 4143 B/op 4 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-1000/Proto3-10 195694 6078 ns/op 5632 B/op 2 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-1000/Arrow-10 224722 5190 ns/op 15544 B/op 66 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-10000/PSDB_Pooled-10 31898 37684 ns/op 41029 B/op 4 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-10000/Proto3-10 20840 58032 ns/op 49408 B/op 2 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-10000/Arrow-10 51440 24049 ns/op 122617 B/op 66 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-100000/PSDB_Pooled-10 3325 357690 ns/op 401814 B/op 4 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-100000/Proto3-10 2158 559694 ns/op 491776 B/op 2 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-100000/Arrow-10 9622 117515 ns/op 957948 B/op 66 allocs/op\nBenchmarkInt32Throughput/Throughput/PSDB-10 290912 4101 ns/op 975.31 MB/s 4143 B/op 4 allocs/op\nBenchmarkInt32Throughput/Throughput/Proto3-10 199087 6005 ns/op 666.12 MB/s 5632 B/op 2 allocs/op\nBenchmarkInt32Throughput/Throughput/Arrow-10 229594 5207 ns/op 768.25 MB/s 15544 B/op 66 allocs/op\nBenchmarkGetPSDBPoolWithoutPool-10 23836599 50.64 ns/op 192 B/op 1 allocs/op\nBenchmarkGetPSDBPoolWithPool-10 100000000 10.76 ns/op 0 B/op 0 allocs/op\nPASS\nok github.com/Meesho/BharatMLStack/online-feature-store/internal/data/blocks 58.891s\n"})}),"\n",(0,o.jsx)(r.hr,{}),"\n",(0,o.jsx)(r.p,{children:(0,o.jsx)(r.em,{children:"Benchmarks run on Apple Silicon (ARM64) with Go 1.22.12. Results may vary on different architectures and Go versions."})})]})}function h(e={}){const{wrapper:r}={...(0,i.R)(),...e.components};return r?(0,o.jsx)(r,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/docs/assets/js/67d4782a.96733ef0.js b/docs/assets/js/67d4782a.96733ef0.js new file mode 100644 index 00000000..dfdae632 --- /dev/null +++ b/docs/assets/js/67d4782a.96733ef0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8588],{8453:(e,r,n)=>{n.d(r,{R:()=>t,x:()=>l});var s=n(6540);const o={},i=s.createContext(o);function t(e){const r=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function l(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),s.createElement(i.Provider,{value:r},e.children)}},8769:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>t,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"online-feature-store/v1.0.0/benchmarks","title":"Benchmarks","description":"Summary","source":"@site/docs/online-feature-store/v1.0.0/benchmarks.md","sourceDirName":"online-feature-store/v1.0.0","slug":"/online-feature-store/v1.0.0/benchmarks","permalink":"/BharatMLStack/online-feature-store/v1.0.0/benchmarks","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/online-feature-store/v1.0.0/benchmarks.md","tags":[],"version":"current","sidebarPosition":3,"frontMatter":{"title":"Benchmarks","sidebar_position":3},"sidebar":"tutorialSidebar","previous":{"title":"Data Formats","permalink":"/BharatMLStack/online-feature-store/v1.0.0/data-formats"},"next":{"title":"Key Functionalities","permalink":"/BharatMLStack/online-feature-store/v1.0.0/functionalities"}}');var o=n(4848),i=n(8453);const t={title:"Benchmarks",sidebar_position:3},l="Serialization Performance Benchmarks",a={},c=[{value:"Summary",id:"summary",level:2},{value:"Test Methodology",id:"test-methodology",level:2},{value:"Environment",id:"environment",level:3},{value:"Test Data",id:"test-data",level:3},{value:"Performance Results",id:"performance-results",level:2},{value:"Serialization Speed (Lower is Better)",id:"serialization-speed-lower-is-better",level:3},{value:"Serialized Size (Lower is Better)",id:"serialized-size-lower-is-better",level:3},{value:"Memory Efficiency (Lower is Better)",id:"memory-efficiency-lower-is-better",level:3},{value:"Throughput (Higher is Better)",id:"throughput-higher-is-better",level:3},{value:"Detailed Analysis",id:"detailed-analysis",level:2},{value:"PSDB Advantages",id:"psdb-advantages",level:3},{value:"Protocol Buffers Analysis",id:"protocol-buffers-analysis",level:3},{value:"Apache Arrow Analysis",id:"apache-arrow-analysis",level:3},{value:"Scaling Characteristics",id:"scaling-characteristics",level:2},{value:"Small Datasets (100-1,000 features)",id:"small-datasets-100-1000-features",level:3},{value:"Large Datasets (10,000+ features)",id:"large-datasets-10000-features",level:3},{value:"Technical Implementation Notes",id:"technical-implementation-notes",level:2},{value:"PSDB Optimizations",id:"psdb-optimizations",level:3},{value:"Memory Layout Comparison",id:"memory-layout-comparison",level:3},{value:"Conclusion",id:"conclusion",level:2},{value:"PSDB: Best for Small-Medium Scale (\u22641,000 features)",id:"psdb-best-for-small-medium-scale-1000-features",level:3},{value:"Apache Arrow: Best for Large Scale (\u226510,000 features)",id:"apache-arrow-best-for-large-scale-10000-features",level:3},{value:"Protocol Buffers: Balanced Middle Ground",id:"protocol-buffers-balanced-middle-ground",level:3},{value:"Raw Benchmark Output [Uncompressed Data]",id:"raw-benchmark-output-uncompressed-data",level:2}];function d(e){const r={code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(r.header,{children:(0,o.jsx)(r.h1,{id:"serialization-performance-benchmarks",children:"Serialization Performance Benchmarks"})}),"\n",(0,o.jsx)(r.h2,{id:"summary",children:"Summary"}),"\n",(0,o.jsx)(r.p,{children:"This report presents comprehensive benchmark results comparing three serialization formats for the BharatML Online Feature Store:"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"PSDB (Permanent Storage Data Block)"})," - Our custom format"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Protocol Buffers v3"})," - Google's binary serialization"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Apache Arrow"})," - Columnar in-memory analytics format"]}),"\n"]}),"\n",(0,o.jsx)(r.p,{children:(0,o.jsx)(r.strong,{children:"Key Findings:"})}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:["\ud83c\udfc6 ",(0,o.jsx)(r.strong,{children:"PSDB excels at small-to-medium scales"})," (100-1,000 features)"]}),"\n",(0,o.jsxs)(r.li,{children:["\u26a1 ",(0,o.jsx)(r.strong,{children:"35% faster"})," than Proto3, but ",(0,o.jsx)(r.strong,{children:"67% slower"})," than Arrow (for 100k features)"]}),"\n",(0,o.jsxs)(r.li,{children:["\ud83d\udce6 ",(0,o.jsx)(r.strong,{children:"18% smaller"})," than Proto3, comparable to Arrow"]}),"\n",(0,o.jsxs)(r.li,{children:["\ud83e\udde0 ",(0,o.jsx)(r.strong,{children:"93% fewer allocations"})," than Arrow (4 vs 66 allocs/op)"]}),"\n"]}),"\n",(0,o.jsx)(r.h2,{id:"test-methodology",children:"Test Methodology"}),"\n",(0,o.jsx)(r.h3,{id:"environment",children:"Environment"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Platform"}),": macOS ARM64 (Apple Silicon)"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Go Version"}),": 1.22.12"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Test Date"}),": January 2025"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Compression"}),": Disabled for fair comparison (",(0,o.jsx)(r.code,{children:"compression.TypeNone"}),")"]}),"\n"]}),"\n",(0,o.jsx)(r.h3,{id:"test-data",children:"Test Data"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Data Type"}),": Int32 arrays"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Feature Group Sizes"}),": 100, 1,000, 10,000, 100,000 features"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Test Iterations"}),": Variable (Go benchmark auto-scaling)"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Pool Optimization"}),": PSDB uses object pooling for memory efficiency"]}),"\n"]}),"\n",(0,o.jsx)(r.h2,{id:"performance-results",children:"Performance Results"}),"\n",(0,o.jsx)(r.h3,{id:"serialization-speed-lower-is-better",children:"Serialization Speed (Lower is Better)"}),"\n",(0,o.jsxs)(r.table,{children:[(0,o.jsx)(r.thead,{children:(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.th,{children:"Feature Count"}),(0,o.jsx)(r.th,{children:"PSDB (ns/op)"}),(0,o.jsx)(r.th,{children:"Proto3 (ns/op)"}),(0,o.jsx)(r.th,{children:"Arrow (ns/op)"}),(0,o.jsx)(r.th,{children:"PSDB vs Proto3"}),(0,o.jsx)(r.th,{children:"PSDB vs Arrow"})]})}),(0,o.jsxs)(r.tbody,{children:[(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"100"}),(0,o.jsx)(r.td,{children:"625"}),(0,o.jsx)(r.td,{children:"696"}),(0,o.jsx)(r.td,{children:"3,831"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"10% faster"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"84% faster"})})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"1,000"}),(0,o.jsx)(r.td,{children:"4,056"}),(0,o.jsx)(r.td,{children:"6,004"}),(0,o.jsx)(r.td,{children:"5,191"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"32% faster"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"22% faster"})})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"10,000"}),(0,o.jsx)(r.td,{children:"37,357"}),(0,o.jsx)(r.td,{children:"57,674"}),(0,o.jsx)(r.td,{children:"23,173"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"35% faster"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"38% slower"})})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"100,000"}),(0,o.jsx)(r.td,{children:"359,932"}),(0,o.jsx)(r.td,{children:"556,541"}),(0,o.jsx)(r.td,{children:"118,489"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"35% faster"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"67% slower"})})]})]})]}),"\n",(0,o.jsx)(r.h3,{id:"serialized-size-lower-is-better",children:"Serialized Size (Lower is Better)"}),"\n",(0,o.jsxs)(r.table,{children:[(0,o.jsx)(r.thead,{children:(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.th,{children:"Feature Count"}),(0,o.jsx)(r.th,{children:"Raw Size (bytes)"}),(0,o.jsx)(r.th,{children:"PSDB (bytes)"}),(0,o.jsx)(r.th,{children:"Proto3 (bytes)"}),(0,o.jsx)(r.th,{children:"Arrow (bytes)"}),(0,o.jsx)(r.th,{children:"PSDB Ratio"}),(0,o.jsx)(r.th,{children:"Proto3 Ratio"}),(0,o.jsx)(r.th,{children:"Arrow Ratio"})]})}),(0,o.jsxs)(r.tbody,{children:[(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"100"}),(0,o.jsx)(r.td,{children:"400"}),(0,o.jsx)(r.td,{children:"409"}),(0,o.jsx)(r.td,{children:"490"}),(0,o.jsx)(r.td,{children:"680"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"102.2%"})}),(0,o.jsx)(r.td,{children:"122.5%"}),(0,o.jsx)(r.td,{children:"170.0%"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"1,000"}),(0,o.jsx)(r.td,{children:"4,000"}),(0,o.jsx)(r.td,{children:"4,009"}),(0,o.jsx)(r.td,{children:"4,881"}),(0,o.jsx)(r.td,{children:"4,280"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"100.2%"})}),(0,o.jsx)(r.td,{children:"122.0%"}),(0,o.jsx)(r.td,{children:"107.0%"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"10,000"}),(0,o.jsx)(r.td,{children:"40,000"}),(0,o.jsx)(r.td,{children:"40,009"}),(0,o.jsx)(r.td,{children:"48,717"}),(0,o.jsx)(r.td,{children:"40,280"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"100.0%"})}),(0,o.jsx)(r.td,{children:"121.8%"}),(0,o.jsx)(r.td,{children:"100.7%"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"100,000"}),(0,o.jsx)(r.td,{children:"400,000"}),(0,o.jsx)(r.td,{children:"400,009"}),(0,o.jsx)(r.td,{children:"487,225"}),(0,o.jsx)(r.td,{children:"400,280"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"100.0%"})}),(0,o.jsx)(r.td,{children:"121.8%"}),(0,o.jsx)(r.td,{children:"100.1%"})]})]})]}),"\n",(0,o.jsx)(r.h3,{id:"memory-efficiency-lower-is-better",children:"Memory Efficiency (Lower is Better)"}),"\n",(0,o.jsxs)(r.table,{children:[(0,o.jsx)(r.thead,{children:(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.th,{children:"Feature Count"}),(0,o.jsx)(r.th,{children:"PSDB (B/op)"}),(0,o.jsx)(r.th,{children:"Proto3 (B/op)"}),(0,o.jsx)(r.th,{children:"Arrow (B/op)"}),(0,o.jsx)(r.th,{children:"PSDB (allocs/op)"}),(0,o.jsx)(r.th,{children:"Proto3 (allocs/op)"}),(0,o.jsx)(r.th,{children:"Arrow (allocs/op)"})]})}),(0,o.jsxs)(r.tbody,{children:[(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"100"}),(0,o.jsx)(r.td,{children:"461"}),(0,o.jsx)(r.td,{children:"768"}),(0,o.jsx)(r.td,{children:"7,032"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"4"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"2"})}),(0,o.jsx)(r.td,{children:"66"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"1,000"}),(0,o.jsx)(r.td,{children:"4,143"}),(0,o.jsx)(r.td,{children:"5,632"}),(0,o.jsx)(r.td,{children:"15,544"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"4"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"2"})}),(0,o.jsx)(r.td,{children:"66"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"10,000"}),(0,o.jsx)(r.td,{children:"41,029"}),(0,o.jsx)(r.td,{children:"49,408"}),(0,o.jsx)(r.td,{children:"122,617"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"4"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"2"})}),(0,o.jsx)(r.td,{children:"66"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"100,000"}),(0,o.jsx)(r.td,{children:"401,814"}),(0,o.jsx)(r.td,{children:"491,776"}),(0,o.jsx)(r.td,{children:"957,948"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"4"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"2"})}),(0,o.jsx)(r.td,{children:"66"})]})]})]}),"\n",(0,o.jsx)(r.h3,{id:"throughput-higher-is-better",children:"Throughput (Higher is Better)"}),"\n",(0,o.jsxs)(r.table,{children:[(0,o.jsx)(r.thead,{children:(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.th,{children:"Format"}),(0,o.jsx)(r.th,{children:"Throughput (MB/s)"}),(0,o.jsx)(r.th,{children:"Relative Performance"})]})}),(0,o.jsxs)(r.tbody,{children:[(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"PSDB"})}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.strong,{children:"975.31"})}),(0,o.jsx)(r.td,{children:"Baseline (100%)"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"Proto3"}),(0,o.jsx)(r.td,{children:"666.12"}),(0,o.jsx)(r.td,{children:"68% of PSDB"})]}),(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"Arrow"}),(0,o.jsx)(r.td,{children:"768.25"}),(0,o.jsx)(r.td,{children:"79% of PSDB"})]})]})]}),"\n",(0,o.jsx)(r.h2,{id:"detailed-analysis",children:"Detailed Analysis"}),"\n",(0,o.jsx)(r.h3,{id:"psdb-advantages",children:"PSDB Advantages"}),"\n",(0,o.jsxs)(r.ol,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Minimal Overhead"}),": Only 9-byte header + raw data"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Optimal Packing"}),": No padding or metadata bloat"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Memory Pooling"}),": Reuses objects to minimize allocations"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Native Optimization"}),": Designed specifically for feature store use cases"]}),"\n"]}),"\n",(0,o.jsx)(r.h3,{id:"protocol-buffers-analysis",children:"Protocol Buffers Analysis"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Consistent Overhead"}),": ~22% size penalty across all scales"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Moderate Speed"}),": Reasonable serialization performance"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Low Allocations"}),": Only 2 allocations per operation"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Varint Encoding"}),": Efficient for smaller integers"]}),"\n"]}),"\n",(0,o.jsx)(r.h3,{id:"apache-arrow-analysis",children:"Apache Arrow Analysis"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"High Setup Cost"}),": Complex object creation (66 allocations)"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Good Large-Scale"}),": Better relative performance with more data"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Size Efficient"}),": Approaches raw data size for large datasets"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Memory Intensive"}),": Significant memory overhead per operation"]}),"\n"]}),"\n",(0,o.jsx)(r.h2,{id:"scaling-characteristics",children:"Scaling Characteristics"}),"\n",(0,o.jsx)(r.h3,{id:"small-datasets-100-1000-features",children:"Small Datasets (100-1,000 features)"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"PSDB"}),": Consistent low overhead"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Proto3"}),": Moderate overhead, stable performance"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Arrow"}),": High setup cost dominates"]}),"\n"]}),"\n",(0,o.jsx)(r.h3,{id:"large-datasets-10000-features",children:"Large Datasets (10,000+ features)"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"PSDB"}),": Linear scaling, maintains efficiency"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Proto3"}),": Good scaling but with consistent 22% size penalty"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Arrow"}),": Better amortization of setup costs"]}),"\n"]}),"\n",(0,o.jsx)(r.h2,{id:"technical-implementation-notes",children:"Technical Implementation Notes"}),"\n",(0,o.jsx)(r.h3,{id:"psdb-optimizations",children:"PSDB Optimizations"}),"\n",(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{className:"language-go",children:"// Object pooling for zero allocations\nvar psdbPool = GetPSDBPool()\n\n// Direct buffer allocation\nheaderSize := PSDBLayout1LengthBytes // 9 bytes\ndataSize := len(data) * 4 // 4 bytes per int32\n\n// No compression for maximum speed\ncompressionType = compression.TypeNone\n"})}),"\n",(0,o.jsx)(r.h3,{id:"memory-layout-comparison",children:"Memory Layout Comparison"}),"\n",(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{children:"PSDB Layout: [9-byte header][raw data]\nProto3 Layout: [varint lengths][encoded data][padding]\nArrow Layout: [schema][metadata][buffers][padding]\n"})}),"\n",(0,o.jsx)(r.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,o.jsxs)(r.p,{children:[(0,o.jsx)(r.strong,{children:"The optimal format depends on your use case and scale"}),":"]}),"\n",(0,o.jsx)(r.h3,{id:"psdb-best-for-small-medium-scale-1000-features",children:(0,o.jsx)(r.strong,{children:"PSDB: Best for Small-Medium Scale (\u22641,000 features)"})}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Excellent speed"}),": Up to 83% faster than Arrow for small datasets"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Optimal size efficiency"}),": Closest to raw data size (100.0-102.2%)"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Memory efficiency"}),": Only 4 allocations per operation"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Low overhead"}),": Minimal 9-byte header"]}),"\n"]}),"\n",(0,o.jsx)(r.h3,{id:"apache-arrow-best-for-large-scale-10000-features",children:(0,o.jsx)(r.strong,{children:"Apache Arrow: Best for Large Scale (\u226510,000 features)"})}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Superior large-scale performance"}),": 67% faster than PSDB at 100k features"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Efficient scaling"}),": Better amortization of setup costs"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Size competitive"}),": Approaches raw data size for large datasets"]}),"\n"]}),"\n",(0,o.jsx)(r.h3,{id:"protocol-buffers-balanced-middle-ground",children:(0,o.jsx)(r.strong,{children:"Protocol Buffers: Balanced Middle Ground"})}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Consistent performance"}),": Moderate speed across all scales"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Standard tooling"}),": Wide ecosystem support"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Predictable overhead"}),": ~22% size penalty but stable"]}),"\n"]}),"\n",(0,o.jsxs)(r.p,{children:[(0,o.jsx)(r.strong,{children:"Recommendation"}),": For the Online Feature Store's typical use patterns with ",(0,o.jsx)(r.strong,{children:"sub-1,000 feature requests"}),", ",(0,o.jsx)(r.strong,{children:"PSDB is the optimal choice"})," for production deployments."]}),"\n",(0,o.jsx)(r.h2,{id:"raw-benchmark-output-uncompressed-data",children:"Raw Benchmark Output [Uncompressed Data]"}),"\n",(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{children:"goos: darwin\ngoarch: arm64\npkg: github.com/Meesho/BharatMLStack/online-feature-store/internal/data/blocks\nBenchmarkInt32SerializationPSDB/PSDB/Size-100-10 1940238 625.3 ns/op 409.0 bytes 461 B/op 4 allocs/op\nBenchmarkInt32SerializationPSDB/PSDB/Size-1000-10 288300 4056 ns/op 4009 bytes 4143 B/op 4 allocs/op\nBenchmarkInt32SerializationPSDB/PSDB/Size-10000-10 32144 37357 ns/op 40009 bytes 41032 B/op 4 allocs/op\nBenchmarkInt32SerializationPSDB/PSDB/Size-100000-10 3244 359932 ns/op 400009 bytes 401572 B/op 4 allocs/op\nBenchmarkInt32SerializationProto3/Proto3/Size-100-10 1703066 695.9 ns/op 486.0 bytes 768 B/op 2 allocs/op\nBenchmarkInt32SerializationProto3/Proto3/Size-1000-10 194142 6004 ns/op 4885 bytes 5632 B/op 2 allocs/op\nBenchmarkInt32SerializationProto3/Proto3/Size-10000-10 20937 57674 ns/op 48734 bytes 49408 B/op 2 allocs/op\nBenchmarkInt32SerializationProto3/Proto3/Size-100000-10 2085 556541 ns/op 487263 bytes 491776 B/op 2 allocs/op\nBenchmarkInt32SerializationArrow/Arrow/Size-100-10 302257 3831 ns/op 680.0 bytes 7032 B/op 66 allocs/op\nBenchmarkInt32SerializationArrow/Arrow/Size-1000-10 228718 5191 ns/op 4280 bytes 15544 B/op 66 allocs/op\nBenchmarkInt32SerializationArrow/Arrow/Size-10000-10 52482 23173 ns/op 40280 bytes 122617 B/op 66 allocs/op\nBenchmarkInt32SerializationArrow/Arrow/Size-100000-10 9765 120081 ns/op 400280 bytes 957948 B/op 66 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-100/PSDB-10 1919401 670.2 ns/op 409.0 bytes 461 B/op 4 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-100/Proto3-10 1733599 693.2 ns/op 490.0 bytes 768 B/op 2 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-100/Arrow-10 304066 3896 ns/op 680.0 bytes 7032 B/op 66 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-1000/PSDB-10 290784 4074 ns/op 4009 bytes 4143 B/op 4 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-1000/Proto3-10 196962 6034 ns/op 4882 bytes 5632 B/op 2 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-1000/Arrow-10 227908 5240 ns/op 4280 bytes 15544 B/op 66 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-10000/PSDB-10 31732 38064 ns/op 40009 bytes 41024 B/op 4 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-10000/Proto3-10 20827 57670 ns/op 48745 bytes 49408 B/op 2 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-10000/Arrow-10 52000 23557 ns/op 40280 bytes 122617 B/op 66 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-100000/PSDB-10 3268 363817 ns/op 400009 bytes 401575 B/op 4 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-100000/Proto3-10 2097 559621 ns/op 487247 bytes 491776 B/op 2 allocs/op\nBenchmarkInt32SerializationComparison/Comparison/Size-100000/Arrow-10 10000 118489 ns/op 400280 bytes 957947 B/op 66 allocs/op\nBenchmarkInt32SizeComparison/SizeOnly/Size-100-10 1000000000 0.0000223 ns/op 680.0 arrow_bytes 170.0 arrow_ratio_pct 490.0 proto3_bytes 122.5 proto3_ratio_pct 409.0 psdb_bytes 102.2 psdb_ratio_pct 400.0 raw_bytes\nBenchmarkInt32SizeComparison/SizeOnly/Size-1000-10 1000000000 0.0000379 ns/op 4280 arrow_bytes 107.0 arrow_ratio_pct 4881 proto3_bytes 122.0 proto3_ratio_pct 4009 psdb_bytes 100.2 psdb_ratio_pct 4000 raw_bytes\nBenchmarkInt32SizeComparison/SizeOnly/Size-10000-10 1000000000 0.0001182 ns/op 40280 arrow_bytes 100.7 arrow_ratio_pct 48717 proto3_bytes 121.8 proto3_ratio_pct 40009 psdb_bytes 100.0 psdb_ratio_pct 40000 raw_bytes\nBenchmarkInt32SizeComparison/SizeOnly/Size-100000-10 1000000000 0.001034 ns/op 400280 arrow_bytes 100.1 arrow_ratio_pct 487225 proto3_bytes 121.8 proto3_ratio_pct 400009 psdb_bytes 100.0 psdb_ratio_pct 400000 raw_bytes\nBenchmarkInt32MemoryEfficiency/Memory/Size-100/PSDB_Pooled-10 1926676 622.4 ns/op 461 B/op 4 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-100/Proto3-10 1713428 685.0 ns/op 768 B/op 2 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-100/Arrow-10 312584 4029 ns/op 7032 B/op 66 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-1000/PSDB_Pooled-10 290197 4189 ns/op 4143 B/op 4 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-1000/Proto3-10 195694 6078 ns/op 5632 B/op 2 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-1000/Arrow-10 224722 5190 ns/op 15544 B/op 66 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-10000/PSDB_Pooled-10 31898 37684 ns/op 41029 B/op 4 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-10000/Proto3-10 20840 58032 ns/op 49408 B/op 2 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-10000/Arrow-10 51440 24049 ns/op 122617 B/op 66 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-100000/PSDB_Pooled-10 3325 357690 ns/op 401814 B/op 4 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-100000/Proto3-10 2158 559694 ns/op 491776 B/op 2 allocs/op\nBenchmarkInt32MemoryEfficiency/Memory/Size-100000/Arrow-10 9622 117515 ns/op 957948 B/op 66 allocs/op\nBenchmarkInt32Throughput/Throughput/PSDB-10 290912 4101 ns/op 975.31 MB/s 4143 B/op 4 allocs/op\nBenchmarkInt32Throughput/Throughput/Proto3-10 199087 6005 ns/op 666.12 MB/s 5632 B/op 2 allocs/op\nBenchmarkInt32Throughput/Throughput/Arrow-10 229594 5207 ns/op 768.25 MB/s 15544 B/op 66 allocs/op\nBenchmarkGetPSDBPoolWithoutPool-10 23836599 50.64 ns/op 192 B/op 1 allocs/op\nBenchmarkGetPSDBPoolWithPool-10 100000000 10.76 ns/op 0 B/op 0 allocs/op\nPASS\nok github.com/Meesho/BharatMLStack/online-feature-store/internal/data/blocks 58.891s\n"})}),"\n",(0,o.jsx)(r.hr,{}),"\n",(0,o.jsx)(r.p,{children:(0,o.jsx)(r.em,{children:"Benchmarks run on Apple Silicon (ARM64) with Go 1.22.12. Results may vary on different architectures and Go versions."})})]})}function h(e={}){const{wrapper:r}={...(0,i.R)(),...e.components};return r?(0,o.jsx)(r,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/docs/assets/js/6870.25f53758.js b/docs/assets/js/6870.25f53758.js new file mode 100644 index 00000000..e0e7d9dc --- /dev/null +++ b/docs/assets/js/6870.25f53758.js @@ -0,0 +1 @@ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6870],{3253:(e,t,n)=>{"use strict";n.d(t,{A:()=>ze});var s=n(6540),a=n(8453),r=n(5260),o=n(2303),c=n(4164),i=n(5293),l=n(6342);function d(){const{prism:e}=(0,l.p)(),{colorMode:t}=(0,i.G)(),n=e.theme,s=e.darkTheme||n;return"dark"===t?s:n}var u=n(7559),m=n(8426),h=n.n(m),f=n(9532),p=n(4848);const g=/title=(?["'])(?.*?)\1/,x=/\{(?<range>[\d,-]+)\}/,j={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},b={...j,lua:{start:"--",end:""},wasm:{start:"\\;\\;",end:""},tex:{start:"%",end:""},vb:{start:"['\u2018\u2019]",end:""},vbnet:{start:"(?:_\\s*)?['\u2018\u2019]",end:""},rem:{start:"[Rr][Ee][Mm]\\b",end:""},f90:{start:"!",end:""},ml:{start:"\\(\\*",end:"\\*\\)"},cobol:{start:"\\*>",end:""}},v=Object.keys(j);function N(e,t){const n=e.map(e=>{const{start:n,end:s}=b[e];return`(?:${n}\\s*(${t.flatMap(e=>[e.line,e.block?.start,e.block?.end].filter(Boolean)).join("|")})\\s*${s})`}).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function y({showLineNumbers:e,metastring:t}){return"boolean"==typeof e?e?1:void 0:"number"==typeof e?e:function(e){const t=e?.split(" ").find(e=>e.startsWith("showLineNumbers"));if(t){if(t.startsWith("showLineNumbers=")){const e=t.replace("showLineNumbers=","");return parseInt(e,10)}return 1}}(t)}function A(e,t){const{language:n,magicComments:s}=t;if(void 0===n)return{lineClassNames:{},code:e};const a=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return N(["js","jsBlock"],t);case"jsx":case"tsx":return N(["js","jsBlock","jsx"],t);case"html":return N(["js","jsBlock","html"],t);case"python":case"py":case"bash":return N(["bash"],t);case"markdown":case"md":return N(["html","jsx","bash"],t);case"tex":case"latex":case"matlab":return N(["tex"],t);case"lua":case"haskell":return N(["lua"],t);case"sql":return N(["lua","jsBlock"],t);case"wasm":return N(["wasm"],t);case"vb":case"vba":case"visual-basic":return N(["vb","rem"],t);case"vbnet":return N(["vbnet","rem"],t);case"batch":return N(["rem"],t);case"basic":return N(["rem","f90"],t);case"fsharp":return N(["js","ml"],t);case"ocaml":case"sml":return N(["ml"],t);case"fortran":return N(["f90"],t);case"cobol":return N(["cobol"],t);default:return N(v,t)}}(n,s),r=e.split(/\r?\n/),o=Object.fromEntries(s.map(e=>[e.className,{start:0,range:""}])),c=Object.fromEntries(s.filter(e=>e.line).map(({className:e,line:t})=>[t,e])),i=Object.fromEntries(s.filter(e=>e.block).map(({className:e,block:t})=>[t.start,e])),l=Object.fromEntries(s.filter(e=>e.block).map(({className:e,block:t})=>[t.end,e]));for(let u=0;u<r.length;){const e=r[u].match(a);if(!e){u+=1;continue}const t=e.slice(1).find(e=>void 0!==e);c[t]?o[c[t]].range+=`${u},`:i[t]?o[i[t]].start=u:l[t]&&(o[l[t]].range+=`${o[l[t]].start}-${u-1},`),r.splice(u,1)}const d={};return Object.entries(o).forEach(([e,{range:t}])=>{h()(t).forEach(t=>{d[t]??=[],d[t].push(e)})}),{code:r.join("\n"),lineClassNames:d}}function w(e,t){const n=e.replace(/\r?\n$/,"");return function(e,{metastring:t,magicComments:n}){if(t&&x.test(t)){const s=t.match(x).groups.range;if(0===n.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${t}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const a=n[0].className,r=h()(s).filter(e=>e>0).map(e=>[e-1,[a]]);return{lineClassNames:Object.fromEntries(r),code:e}}return null}(n,{...t})??A(n,{...t})}function C(e){const t=function(e){return t=e.language??function(e){if(!e)return;const t=e.split(" ").find(e=>e.startsWith("language-"));return t?.replace(/language-/,"")}(e.className)??e.defaultLanguage,t?.toLowerCase()??"text";var t}({language:e.language,defaultLanguage:e.defaultLanguage,className:e.className}),{lineClassNames:n,code:s}=w(e.code,{metastring:e.metastring,magicComments:e.magicComments,language:t}),a=function({className:e,language:t}){return(0,c.A)(e,t&&!e?.includes(`language-${t}`)&&`language-${t}`)}({className:e.className,language:t}),r=(o=e.metastring,(o?.match(g)?.groups.title??"")||e.title);var o;const i=y({showLineNumbers:e.showLineNumbers,metastring:e.metastring});return{codeInput:e.code,code:s,className:a,language:t,title:r,lineNumbersStart:i,lineClassNames:n}}const k=(0,s.createContext)(null);function B({metadata:e,wordWrap:t,children:n}){const a=(0,s.useMemo)(()=>({metadata:e,wordWrap:t}),[e,t]);return(0,p.jsx)(k.Provider,{value:a,children:n})}function E(){const e=(0,s.useContext)(k);if(null===e)throw new f.dV("CodeBlockContextProvider");return e}const L="codeBlockContainer_Ckt0";function T({as:e,...t}){const n=function(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach(([e,s])=>{const a=t[e];a&&"string"==typeof s&&(n[a]=s)}),n}(d());return(0,p.jsx)(e,{...t,style:n,className:(0,c.A)(t.className,L,u.G.common.codeBlock)})}const _="codeBlock_bY9V",M="codeBlockStandalone_MEMb",S="codeBlockLines_e6Vv",U="codeBlockLinesWithNumbering_o6Pm";function z({children:e,className:t}){return(0,p.jsx)(T,{as:"pre",tabIndex:0,className:(0,c.A)(M,"thin-scrollbar",t),children:(0,p.jsx)("code",{className:S,children:e})})}const I={attributes:!0,characterData:!0,childList:!0,subtree:!0};function H(e,t){const[n,a]=(0,s.useState)(),r=(0,s.useCallback)(()=>{a(e.current?.closest("[role=tabpanel][hidden]"))},[e,a]);(0,s.useEffect)(()=>{r()},[r]),function(e,t,n=I){const a=(0,f._q)(t),r=(0,f.Be)(n);(0,s.useEffect)(()=>{const t=new MutationObserver(a);return e&&t.observe(e,r),()=>t.disconnect()},[e,a,r])}(n,e=>{e.forEach(e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),r())})},{attributes:!0,characterData:!1,childList:!1,subtree:!1})}function R({children:e}){return e}var V=n(1765);function P({line:e,token:t,...n}){return(0,p.jsx)("span",{...n})}const W="codeLine_lJS_",$="codeLineNumber_Tfdd",D="codeLineContent_feaV";function q({line:e,classNames:t,showLineNumbers:n,getLineProps:s,getTokenProps:a}){const r=function(e){const t=1===e.length&&"\n"===e[0].content?e[0]:void 0;return t?[{...t,content:""}]:e}(e),o=s({line:r,className:(0,c.A)(t,n&&W)}),i=r.map((e,t)=>{const n=a({token:e});return(0,p.jsx)(P,{...n,line:r,token:e,children:n.children},t)});return(0,p.jsxs)("span",{...o,children:[n?(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("span",{className:$}),(0,p.jsx)("span",{className:D,children:i})]}):i,(0,p.jsx)("br",{})]})}const O=s.forwardRef((e,t)=>(0,p.jsx)("pre",{ref:t,tabIndex:0,...e,className:(0,c.A)(e.className,_,"thin-scrollbar")}));function F(e){const{metadata:t}=E();return(0,p.jsx)("code",{...e,className:(0,c.A)(e.className,S,void 0!==t.lineNumbersStart&&U),style:{...e.style,counterReset:void 0===t.lineNumbersStart?void 0:"line-count "+(t.lineNumbersStart-1)}})}function G({className:e}){const{metadata:t,wordWrap:n}=E(),s=d(),{code:a,language:r,lineNumbersStart:o,lineClassNames:i}=t;return(0,p.jsx)(V.f4,{theme:s,code:a,language:r,children:({className:t,style:s,tokens:a,getLineProps:r,getTokenProps:l})=>(0,p.jsx)(O,{ref:n.codeBlockRef,className:(0,c.A)(e,t),style:s,children:(0,p.jsx)(F,{children:a.map((e,t)=>(0,p.jsx)(q,{line:e,getLineProps:r,getTokenProps:l,classNames:i[t],showLineNumbers:void 0!==o},t))})})})}function J({children:e,fallback:t}){return(0,o.A)()?(0,p.jsx)(p.Fragment,{children:e?.()}):t??null}var Z=n(1312);function Y({className:e,...t}){return(0,p.jsx)("button",{type:"button",...t,className:(0,c.A)("clean-btn",e)})}function Q(e){return(0,p.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,p.jsx)("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})})}function X(e){return(0,p.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,p.jsx)("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"})})}const K={copyButtonCopied:"copyButtonCopied_Vdqa",copyButtonIcons:"copyButtonIcons_IEyt",copyButtonIcon:"copyButtonIcon_TrPX",copyButtonSuccessIcon:"copyButtonSuccessIcon_cVMy"};function ee(e){return e?(0,Z.T)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,Z.T)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"})}function te(){const{metadata:{code:e}}=E(),[t,n]=(0,s.useState)(!1),a=(0,s.useRef)(void 0),r=(0,s.useCallback)(()=>{!function(e,{target:t=document.body}={}){if("string"!=typeof e)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof e}\`.`);const n=document.createElement("textarea"),s=document.activeElement;n.value=e,n.setAttribute("readonly",""),n.style.all="unset",n.style.contain="strict",n.style.position="absolute",n.style.left="-9999px",n.style.width="2em",n.style.height="2em",n.style.padding="0",n.style.border="none",n.style.outline="none",n.style.boxShadow="none",n.style.background="transparent",n.style.fontSize="12pt";const a=document.getSelection(),r=a.rangeCount>0&&a.getRangeAt(0);t.append(n),n.select(),n.selectionStart=0,n.selectionEnd=e.length;let o=!1;try{o=document.execCommand("copy")}catch{}n.remove(),r&&(a.removeAllRanges(),a.addRange(r)),s&&s.focus()}(e),n(!0),a.current=window.setTimeout(()=>{n(!1)},1e3)},[e]);return(0,s.useEffect)(()=>()=>window.clearTimeout(a.current),[]),{copyCode:r,isCopied:t}}function ne({className:e}){const{copyCode:t,isCopied:n}=te();return(0,p.jsx)(Y,{"aria-label":ee(n),title:(0,Z.T)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,c.A)(e,K.copyButton,n&&K.copyButtonCopied),onClick:t,children:(0,p.jsxs)("span",{className:K.copyButtonIcons,"aria-hidden":"true",children:[(0,p.jsx)(Q,{className:K.copyButtonIcon}),(0,p.jsx)(X,{className:K.copyButtonSuccessIcon})]})})}function se(e){return(0,p.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,p.jsx)("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})})}const ae="wordWrapButtonIcon_b1P5",re="wordWrapButtonEnabled_uzNF";function oe({className:e}){const{wordWrap:t}=E();if(!(t.isEnabled||t.isCodeScrollable))return!1;const n=(0,Z.T)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return(0,p.jsx)(Y,{onClick:()=>t.toggle(),className:(0,c.A)(e,t.isEnabled&&re),"aria-label":n,title:n,children:(0,p.jsx)(se,{className:ae,"aria-hidden":"true"})})}const ce="buttonGroup_M5ko";function ie({className:e}){return(0,p.jsx)(J,{children:()=>(0,p.jsxs)("div",{className:(0,c.A)(e,ce),children:[(0,p.jsx)(oe,{}),(0,p.jsx)(ne,{})]})})}const le="codeBlockContent_QJqH",de="codeBlockTitle_OeMC";function ue({className:e}){const{metadata:t}=E();return(0,p.jsxs)(T,{as:"div",className:(0,c.A)(e,t.className),children:[t.title&&(0,p.jsx)("div",{className:de,children:(0,p.jsx)(R,{children:t.title})}),(0,p.jsxs)("div",{className:le,children:[(0,p.jsx)(G,{}),(0,p.jsx)(ie,{})]})]})}function me(e){const t=function(e){const{prism:t}=(0,l.p)();return C({code:e.children,className:e.className,metastring:e.metastring,magicComments:t.magicComments,defaultLanguage:t.defaultLanguage,language:e.language,title:e.title,showLineNumbers:e.showLineNumbers})}(e),n=function(){const[e,t]=(0,s.useState)(!1),[n,a]=(0,s.useState)(!1),r=(0,s.useRef)(null),o=(0,s.useCallback)(()=>{const n=r.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t(e=>!e)},[r,e]),c=(0,s.useCallback)(()=>{const{scrollWidth:e,clientWidth:t}=r.current,n=e>t||r.current.querySelector("code").hasAttribute("style");a(n)},[r]);return H(r,c),(0,s.useEffect)(()=>{c()},[e,c]),(0,s.useEffect)(()=>(window.addEventListener("resize",c,{passive:!0}),()=>{window.removeEventListener("resize",c)}),[c]),{codeBlockRef:r,isEnabled:e,isCodeScrollable:n,toggle:o}}();return(0,p.jsx)(B,{metadata:t,wordWrap:n,children:(0,p.jsx)(ue,{})})}function he({children:e,...t}){const n=(0,o.A)(),a=function(e){return s.Children.toArray(e).some(e=>(0,s.isValidElement)(e))?e:Array.isArray(e)?e.join(""):e}(e),r="string"==typeof a?me:z;return(0,p.jsx)(r,{...t,children:a},String(n))}function fe(e){return(0,p.jsx)("code",{...e})}var pe=n(8774);var ge=n(3427),xe=n(1422);const je="details_lb9f",be="isBrowser_bmU9",ve="collapsibleContent_i85q";function Ne(e){return!!e&&("SUMMARY"===e.tagName||Ne(e.parentElement))}function ye(e,t){return!!e&&(e===t||ye(e.parentElement,t))}function Ae({summary:e,children:t,...n}){(0,ge.A)().collectAnchor(n.id);const a=(0,o.A)(),r=(0,s.useRef)(null),{collapsed:i,setCollapsed:l}=(0,xe.u)({initialState:!n.open}),[d,u]=(0,s.useState)(n.open),m=s.isValidElement(e)?e:(0,p.jsx)("summary",{children:e??"Details"});return(0,p.jsxs)("details",{...n,ref:r,open:d,"data-collapsed":i,className:(0,c.A)(je,a&&be,n.className),onMouseDown:e=>{Ne(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;Ne(t)&&ye(t,r.current)&&(e.preventDefault(),i?(l(!1),u(!0)):l(!0))},children:[m,(0,p.jsx)(xe.N,{lazy:!1,collapsed:i,onCollapseTransitionEnd:e=>{l(e),u(!e)},children:(0,p.jsx)("div",{className:ve,children:t})})]})}const we="details_b_Ee";function Ce({...e}){return(0,p.jsx)(Ae,{...e,className:(0,c.A)("alert alert--info",we,e.className)})}function ke(e){const t=s.Children.toArray(e.children),n=t.find(e=>s.isValidElement(e)&&"summary"===e.type),a=(0,p.jsx)(p.Fragment,{children:t.filter(e=>e!==n)});return(0,p.jsx)(Ce,{...e,summary:n,children:a})}var Be=n(1107);function Ee(e){return(0,p.jsx)(Be.A,{...e})}const Le="containsTaskList_mC6p";function Te(e){if(void 0!==e)return(0,c.A)(e,e?.includes("contains-task-list")&&Le)}const _e="img_ev3q";var Me=n(7293),Se=n(418);const Ue={Head:r.A,details:ke,Details:ke,code:function(e){return function(e){return void 0!==e.children&&s.Children.toArray(e.children).every(e=>"string"==typeof e&&!e.includes("\n"))}(e)?(0,p.jsx)(fe,{...e}):(0,p.jsx)(he,{...e})},a:function(e){return(0,p.jsx)(pe.A,{...e})},pre:function(e){return(0,p.jsx)(p.Fragment,{children:e.children})},ul:function(e){return(0,p.jsx)("ul",{...e,className:Te(e.className)})},li:function(e){return(0,ge.A)().collectAnchor(e.id),(0,p.jsx)("li",{...e})},img:function(e){return(0,p.jsx)("img",{decoding:"async",loading:"lazy",...e,className:(t=e.className,(0,c.A)(t,_e))});var t},h1:e=>(0,p.jsx)(Ee,{as:"h1",...e}),h2:e=>(0,p.jsx)(Ee,{as:"h2",...e}),h3:e=>(0,p.jsx)(Ee,{as:"h3",...e}),h4:e=>(0,p.jsx)(Ee,{as:"h4",...e}),h5:e=>(0,p.jsx)(Ee,{as:"h5",...e}),h6:e=>(0,p.jsx)(Ee,{as:"h6",...e}),admonition:Me.A,mermaid:Se.A};function ze({children:e}){return(0,p.jsx)(a.x,{components:Ue,children:e})}},4336:(e,t,n)=>{"use strict";n.d(t,{A:()=>g});n(6540);var s=n(4164),a=n(1312),r=n(7559),o=n(8774);const c={iconEdit:"iconEdit_Z9Sw"};var i=n(4848);function l({className:e,...t}){return(0,i.jsx)("svg",{fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,s.A)(c.iconEdit,e),"aria-hidden":"true",...t,children:(0,i.jsx)("g",{children:(0,i.jsx)("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})})})}function d({editUrl:e}){return(0,i.jsxs)(o.A,{to:e,className:r.G.common.editThisPage,children:[(0,i.jsx)(l,{}),(0,i.jsx)(a.A,{id:"theme.common.editThisPage",description:"The link label to edit the current page",children:"Edit this page"})]})}var u=n(6266);function m({lastUpdatedAt:e}){const t=new Date(e),n=(0,u.i)({day:"numeric",month:"short",year:"numeric",timeZone:"UTC"}).format(t);return(0,i.jsx)(a.A,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:(0,i.jsx)("b",{children:(0,i.jsx)("time",{dateTime:t.toISOString(),itemProp:"dateModified",children:n})})},children:" on {date}"})}function h({lastUpdatedBy:e}){return(0,i.jsx)(a.A,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:(0,i.jsx)("b",{children:e})},children:" by {user}"})}function f({lastUpdatedAt:e,lastUpdatedBy:t}){return(0,i.jsxs)("span",{className:r.G.common.lastUpdated,children:[(0,i.jsx)(a.A,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:e?(0,i.jsx)(m,{lastUpdatedAt:e}):"",byUser:t?(0,i.jsx)(h,{lastUpdatedBy:t}):""},children:"Last updated{atDate}{byUser}"}),!1]})}const p={lastUpdated:"lastUpdated_JAkA"};function g({className:e,editUrl:t,lastUpdatedAt:n,lastUpdatedBy:a}){return(0,i.jsxs)("div",{className:(0,s.A)("row",e),children:[(0,i.jsx)("div",{className:"col",children:t&&(0,i.jsx)(d,{editUrl:t})}),(0,i.jsx)("div",{className:(0,s.A)("col",p.lastUpdated),children:(n||a)&&(0,i.jsx)(f,{lastUpdatedAt:n,lastUpdatedBy:a})})]})}},6266:(e,t,n)=>{"use strict";n.d(t,{i:()=>a});var s=n(4586);function a(e={}){const{i18n:{currentLocale:t}}=(0,s.A)(),n=function(){const{i18n:{currentLocale:e,localeConfigs:t}}=(0,s.A)();return t[e].calendar}();return new Intl.DateTimeFormat(t,{calendar:n,...e})}},7293:(e,t,n)=>{"use strict";n.d(t,{A:()=>M});var s=n(6540),a=n(4848);function r(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=s.Children.toArray(e),n=t.find(e=>s.isValidElement(e)&&"mdxAdmonitionTitle"===e.type),r=t.filter(e=>e!==n),o=n?.props.children;return{mdxAdmonitionTitle:o,rest:r.length>0?(0,a.jsx)(a.Fragment,{children:r}):null}}(e.children),r=e.title??t;return{...e,...r&&{title:r},children:n}}var o=n(4164),c=n(1312),i=n(7559);const l="admonition_xJq3",d="admonitionHeading_Gvgb",u="admonitionIcon_Rf37",m="admonitionContent_BuS1";function h({type:e,className:t,children:n}){return(0,a.jsx)("div",{className:(0,o.A)(i.G.common.admonition,i.G.common.admonitionType(e),l,t),children:n})}function f({icon:e,title:t}){return(0,a.jsxs)("div",{className:d,children:[(0,a.jsx)("span",{className:u,children:e}),t]})}function p({children:e}){return e?(0,a.jsx)("div",{className:m,children:e}):null}function g(e){const{type:t,icon:n,title:s,children:r,className:o}=e;return(0,a.jsxs)(h,{type:t,className:o,children:[s||n?(0,a.jsx)(f,{title:s,icon:n}):null,(0,a.jsx)(p,{children:r})]})}function x(e){return(0,a.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const j={icon:(0,a.jsx)(x,{}),title:(0,a.jsx)(c.A,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function b(e){return(0,a.jsx)(g,{...j,...e,className:(0,o.A)("alert alert--secondary",e.className),children:e.children})}function v(e){return(0,a.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const N={icon:(0,a.jsx)(v,{}),title:(0,a.jsx)(c.A,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function y(e){return(0,a.jsx)(g,{...N,...e,className:(0,o.A)("alert alert--success",e.className),children:e.children})}function A(e){return(0,a.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const w={icon:(0,a.jsx)(A,{}),title:(0,a.jsx)(c.A,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function C(e){return(0,a.jsx)(g,{...w,...e,className:(0,o.A)("alert alert--info",e.className),children:e.children})}function k(e){return(0,a.jsx)("svg",{viewBox:"0 0 16 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const B={icon:(0,a.jsx)(k,{}),title:(0,a.jsx)(c.A,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function E(e){return(0,a.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const L={icon:(0,a.jsx)(E,{}),title:(0,a.jsx)(c.A,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const T={icon:(0,a.jsx)(k,{}),title:(0,a.jsx)(c.A,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const _={...{note:b,tip:y,info:C,warning:function(e){return(0,a.jsx)(g,{...B,...e,className:(0,o.A)("alert alert--warning",e.className),children:e.children})},danger:function(e){return(0,a.jsx)(g,{...L,...e,className:(0,o.A)("alert alert--danger",e.className),children:e.children})}},...{secondary:e=>(0,a.jsx)(b,{title:"secondary",...e}),important:e=>(0,a.jsx)(C,{title:"important",...e}),success:e=>(0,a.jsx)(y,{title:"success",...e}),caution:function(e){return(0,a.jsx)(g,{...T,...e,className:(0,o.A)("alert alert--warning",e.className),children:e.children})}}};function M(e){const t=r(e),n=(s=t.type,_[s]||(console.warn(`No admonition component found for admonition type "${s}". Using Info as fallback.`),_.info));var s;return(0,a.jsx)(n,{...t})}},8426:(e,t)=>{function n(e){let t,n=[];for(let s of e.split(",").map(e=>e.trim()))if(/^-?\d+$/.test(s))n.push(parseInt(s,10));else if(t=s.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,s,a,r]=t;if(s&&r){s=parseInt(s),r=parseInt(r);const e=s<r?1:-1;"-"!==a&&".."!==a&&"\u2025"!==a||(r+=e);for(let t=s;t!==r;t+=e)n.push(t)}}return n}t.default=n,e.exports=n},8453:(e,t,n)=>{"use strict";n.d(t,{R:()=>o,x:()=>c});var s=n(6540);const a={},r=s.createContext(a);function o(e){const t=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/6870.6d10e1d8.js b/docs/assets/js/6870.6d10e1d8.js deleted file mode 100644 index 092c2d9d..00000000 --- a/docs/assets/js/6870.6d10e1d8.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6870],{3253:(e,t,n)=>{"use strict";n.d(t,{A:()=>ze});var s=n(6540),a=n(8453),r=n(5260),c=n(2303),o=n(4164),i=n(5293),l=n(6342);function d(){const{prism:e}=(0,l.p)(),{colorMode:t}=(0,i.G)(),n=e.theme,s=e.darkTheme||n;return"dark"===t?s:n}var u=n(7559),m=n(8426),h=n.n(m),f=n(9532),p=n(4848);const g=/title=(?<quote>["'])(?<title>.*?)\1/,x=/\{(?<range>[\d,-]+)\}/,j={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},b={...j,lua:{start:"--",end:""},wasm:{start:"\\;\\;",end:""},tex:{start:"%",end:""},vb:{start:"['\u2018\u2019]",end:""},vbnet:{start:"(?:_\\s*)?['\u2018\u2019]",end:""},rem:{start:"[Rr][Ee][Mm]\\b",end:""},f90:{start:"!",end:""},ml:{start:"\\(\\*",end:"\\*\\)"},cobol:{start:"\\*>",end:""}},v=Object.keys(j);function N(e,t){const n=e.map((e=>{const{start:n,end:s}=b[e];return`(?:${n}\\s*(${t.flatMap((e=>[e.line,e.block?.start,e.block?.end].filter(Boolean))).join("|")})\\s*${s})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function y({showLineNumbers:e,metastring:t}){return"boolean"==typeof e?e?1:void 0:"number"==typeof e?e:function(e){const t=e?.split(" ").find((e=>e.startsWith("showLineNumbers")));if(t){if(t.startsWith("showLineNumbers=")){const e=t.replace("showLineNumbers=","");return parseInt(e,10)}return 1}}(t)}function A(e,t){const{language:n,magicComments:s}=t;if(void 0===n)return{lineClassNames:{},code:e};const a=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return N(["js","jsBlock"],t);case"jsx":case"tsx":return N(["js","jsBlock","jsx"],t);case"html":return N(["js","jsBlock","html"],t);case"python":case"py":case"bash":return N(["bash"],t);case"markdown":case"md":return N(["html","jsx","bash"],t);case"tex":case"latex":case"matlab":return N(["tex"],t);case"lua":case"haskell":return N(["lua"],t);case"sql":return N(["lua","jsBlock"],t);case"wasm":return N(["wasm"],t);case"vb":case"vba":case"visual-basic":return N(["vb","rem"],t);case"vbnet":return N(["vbnet","rem"],t);case"batch":return N(["rem"],t);case"basic":return N(["rem","f90"],t);case"fsharp":return N(["js","ml"],t);case"ocaml":case"sml":return N(["ml"],t);case"fortran":return N(["f90"],t);case"cobol":return N(["cobol"],t);default:return N(v,t)}}(n,s),r=e.split(/\r?\n/),c=Object.fromEntries(s.map((e=>[e.className,{start:0,range:""}]))),o=Object.fromEntries(s.filter((e=>e.line)).map((({className:e,line:t})=>[t,e]))),i=Object.fromEntries(s.filter((e=>e.block)).map((({className:e,block:t})=>[t.start,e]))),l=Object.fromEntries(s.filter((e=>e.block)).map((({className:e,block:t})=>[t.end,e])));for(let u=0;u<r.length;){const e=r[u].match(a);if(!e){u+=1;continue}const t=e.slice(1).find((e=>void 0!==e));o[t]?c[o[t]].range+=`${u},`:i[t]?c[i[t]].start=u:l[t]&&(c[l[t]].range+=`${c[l[t]].start}-${u-1},`),r.splice(u,1)}const d={};return Object.entries(c).forEach((([e,{range:t}])=>{h()(t).forEach((t=>{d[t]??=[],d[t].push(e)}))})),{code:r.join("\n"),lineClassNames:d}}function w(e,t){const n=e.replace(/\r?\n$/,"");return function(e,{metastring:t,magicComments:n}){if(t&&x.test(t)){const s=t.match(x).groups.range;if(0===n.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${t}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const a=n[0].className,r=h()(s).filter((e=>e>0)).map((e=>[e-1,[a]]));return{lineClassNames:Object.fromEntries(r),code:e}}return null}(n,{...t})??A(n,{...t})}function C(e){const t=function(e){return t=e.language??function(e){if(!e)return;const t=e.split(" ").find((e=>e.startsWith("language-")));return t?.replace(/language-/,"")}(e.className)??e.defaultLanguage,t?.toLowerCase()??"text";var t}({language:e.language,defaultLanguage:e.defaultLanguage,className:e.className}),{lineClassNames:n,code:s}=w(e.code,{metastring:e.metastring,magicComments:e.magicComments,language:t}),a=function({className:e,language:t}){return(0,o.A)(e,t&&!e?.includes(`language-${t}`)&&`language-${t}`)}({className:e.className,language:t}),r=(c=e.metastring,(c?.match(g)?.groups.title??"")||e.title);var c;const i=y({showLineNumbers:e.showLineNumbers,metastring:e.metastring});return{codeInput:e.code,code:s,className:a,language:t,title:r,lineNumbersStart:i,lineClassNames:n}}const k=(0,s.createContext)(null);function B({metadata:e,wordWrap:t,children:n}){const a=(0,s.useMemo)((()=>({metadata:e,wordWrap:t})),[e,t]);return(0,p.jsx)(k.Provider,{value:a,children:n})}function E(){const e=(0,s.useContext)(k);if(null===e)throw new f.dV("CodeBlockContextProvider");return e}const L="codeBlockContainer_Ckt0";function T({as:e,...t}){const n=function(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((([e,s])=>{const a=t[e];a&&"string"==typeof s&&(n[a]=s)})),n}(d());return(0,p.jsx)(e,{...t,style:n,className:(0,o.A)(t.className,L,u.G.common.codeBlock)})}const _="codeBlock_bY9V",M="codeBlockStandalone_MEMb",S="codeBlockLines_e6Vv",U="codeBlockLinesWithNumbering_o6Pm";function z({children:e,className:t}){return(0,p.jsx)(T,{as:"pre",tabIndex:0,className:(0,o.A)(M,"thin-scrollbar",t),children:(0,p.jsx)("code",{className:S,children:e})})}const I={attributes:!0,characterData:!0,childList:!0,subtree:!0};function H(e,t){const[n,a]=(0,s.useState)(),r=(0,s.useCallback)((()=>{a(e.current?.closest("[role=tabpanel][hidden]"))}),[e,a]);(0,s.useEffect)((()=>{r()}),[r]),function(e,t,n=I){const a=(0,f._q)(t),r=(0,f.Be)(n);(0,s.useEffect)((()=>{const t=new MutationObserver(a);return e&&t.observe(e,r),()=>t.disconnect()}),[e,a,r])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),r())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}function R({children:e}){return e}var V=n(1765);function P({line:e,token:t,...n}){return(0,p.jsx)("span",{...n})}const W="codeLine_lJS_",$="codeLineNumber_Tfdd",D="codeLineContent_feaV";function q({line:e,classNames:t,showLineNumbers:n,getLineProps:s,getTokenProps:a}){const r=function(e){const t=1===e.length&&"\n"===e[0].content?e[0]:void 0;return t?[{...t,content:""}]:e}(e),c=s({line:r,className:(0,o.A)(t,n&&W)}),i=r.map(((e,t)=>{const n=a({token:e});return(0,p.jsx)(P,{...n,line:r,token:e,children:n.children},t)}));return(0,p.jsxs)("span",{...c,children:[n?(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("span",{className:$}),(0,p.jsx)("span",{className:D,children:i})]}):i,(0,p.jsx)("br",{})]})}const O=s.forwardRef(((e,t)=>(0,p.jsx)("pre",{ref:t,tabIndex:0,...e,className:(0,o.A)(e.className,_,"thin-scrollbar")})));function F(e){const{metadata:t}=E();return(0,p.jsx)("code",{...e,className:(0,o.A)(e.className,S,void 0!==t.lineNumbersStart&&U),style:{...e.style,counterReset:void 0===t.lineNumbersStart?void 0:"line-count "+(t.lineNumbersStart-1)}})}function G({className:e}){const{metadata:t,wordWrap:n}=E(),s=d(),{code:a,language:r,lineNumbersStart:c,lineClassNames:i}=t;return(0,p.jsx)(V.f4,{theme:s,code:a,language:r,children:({className:t,style:s,tokens:a,getLineProps:r,getTokenProps:l})=>(0,p.jsx)(O,{ref:n.codeBlockRef,className:(0,o.A)(e,t),style:s,children:(0,p.jsx)(F,{children:a.map(((e,t)=>(0,p.jsx)(q,{line:e,getLineProps:r,getTokenProps:l,classNames:i[t],showLineNumbers:void 0!==c},t)))})})})}function J({children:e,fallback:t}){return(0,c.A)()?(0,p.jsx)(p.Fragment,{children:e?.()}):t??null}var Z=n(1312);function Y({className:e,...t}){return(0,p.jsx)("button",{type:"button",...t,className:(0,o.A)("clean-btn",e)})}function Q(e){return(0,p.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,p.jsx)("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})})}function X(e){return(0,p.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,p.jsx)("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"})})}const K={copyButtonCopied:"copyButtonCopied_Vdqa",copyButtonIcons:"copyButtonIcons_IEyt",copyButtonIcon:"copyButtonIcon_TrPX",copyButtonSuccessIcon:"copyButtonSuccessIcon_cVMy"};function ee(e){return e?(0,Z.T)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,Z.T)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"})}function te(){const{metadata:{code:e}}=E(),[t,n]=(0,s.useState)(!1),a=(0,s.useRef)(void 0),r=(0,s.useCallback)((()=>{!function(e,{target:t=document.body}={}){if("string"!=typeof e)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof e}\`.`);const n=document.createElement("textarea"),s=document.activeElement;n.value=e,n.setAttribute("readonly",""),n.style.contain="strict",n.style.position="absolute",n.style.left="-9999px",n.style.fontSize="12pt";const a=document.getSelection(),r=a.rangeCount>0&&a.getRangeAt(0);t.append(n),n.select(),n.selectionStart=0,n.selectionEnd=e.length;let c=!1;try{c=document.execCommand("copy")}catch{}n.remove(),r&&(a.removeAllRanges(),a.addRange(r)),s&&s.focus()}(e),n(!0),a.current=window.setTimeout((()=>{n(!1)}),1e3)}),[e]);return(0,s.useEffect)((()=>()=>window.clearTimeout(a.current)),[]),{copyCode:r,isCopied:t}}function ne({className:e}){const{copyCode:t,isCopied:n}=te();return(0,p.jsx)(Y,{"aria-label":ee(n),title:(0,Z.T)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,o.A)(e,K.copyButton,n&&K.copyButtonCopied),onClick:t,children:(0,p.jsxs)("span",{className:K.copyButtonIcons,"aria-hidden":"true",children:[(0,p.jsx)(Q,{className:K.copyButtonIcon}),(0,p.jsx)(X,{className:K.copyButtonSuccessIcon})]})})}function se(e){return(0,p.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,p.jsx)("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})})}const ae="wordWrapButtonIcon_b1P5",re="wordWrapButtonEnabled_uzNF";function ce({className:e}){const{wordWrap:t}=E();if(!(t.isEnabled||t.isCodeScrollable))return!1;const n=(0,Z.T)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return(0,p.jsx)(Y,{onClick:()=>t.toggle(),className:(0,o.A)(e,t.isEnabled&&re),"aria-label":n,title:n,children:(0,p.jsx)(se,{className:ae,"aria-hidden":"true"})})}const oe="buttonGroup_M5ko";function ie({className:e}){return(0,p.jsx)(J,{children:()=>(0,p.jsxs)("div",{className:(0,o.A)(e,oe),children:[(0,p.jsx)(ce,{}),(0,p.jsx)(ne,{})]})})}const le="codeBlockContent_QJqH",de="codeBlockTitle_OeMC";function ue({className:e}){const{metadata:t}=E();return(0,p.jsxs)(T,{as:"div",className:(0,o.A)(e,t.className),children:[t.title&&(0,p.jsx)("div",{className:de,children:(0,p.jsx)(R,{children:t.title})}),(0,p.jsxs)("div",{className:le,children:[(0,p.jsx)(G,{}),(0,p.jsx)(ie,{})]})]})}function me(e){const t=function(e){const{prism:t}=(0,l.p)();return C({code:e.children,className:e.className,metastring:e.metastring,magicComments:t.magicComments,defaultLanguage:t.defaultLanguage,language:e.language,title:e.title,showLineNumbers:e.showLineNumbers})}(e),n=function(){const[e,t]=(0,s.useState)(!1),[n,a]=(0,s.useState)(!1),r=(0,s.useRef)(null),c=(0,s.useCallback)((()=>{const n=r.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[r,e]),o=(0,s.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=r.current,n=e>t||r.current.querySelector("code").hasAttribute("style");a(n)}),[r]);return H(r,o),(0,s.useEffect)((()=>{o()}),[e,o]),(0,s.useEffect)((()=>(window.addEventListener("resize",o,{passive:!0}),()=>{window.removeEventListener("resize",o)})),[o]),{codeBlockRef:r,isEnabled:e,isCodeScrollable:n,toggle:c}}();return(0,p.jsx)(B,{metadata:t,wordWrap:n,children:(0,p.jsx)(ue,{})})}function he({children:e,...t}){const n=(0,c.A)(),a=function(e){return s.Children.toArray(e).some((e=>(0,s.isValidElement)(e)))?e:Array.isArray(e)?e.join(""):e}(e),r="string"==typeof a?me:z;return(0,p.jsx)(r,{...t,children:a},String(n))}function fe(e){return(0,p.jsx)("code",{...e})}var pe=n(8774);var ge=n(3427),xe=n(1422);const je="details_lb9f",be="isBrowser_bmU9",ve="collapsibleContent_i85q";function Ne(e){return!!e&&("SUMMARY"===e.tagName||Ne(e.parentElement))}function ye(e,t){return!!e&&(e===t||ye(e.parentElement,t))}function Ae({summary:e,children:t,...n}){(0,ge.A)().collectAnchor(n.id);const a=(0,c.A)(),r=(0,s.useRef)(null),{collapsed:i,setCollapsed:l}=(0,xe.u)({initialState:!n.open}),[d,u]=(0,s.useState)(n.open),m=s.isValidElement(e)?e:(0,p.jsx)("summary",{children:e??"Details"});return(0,p.jsxs)("details",{...n,ref:r,open:d,"data-collapsed":i,className:(0,o.A)(je,a&&be,n.className),onMouseDown:e=>{Ne(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;Ne(t)&&ye(t,r.current)&&(e.preventDefault(),i?(l(!1),u(!0)):l(!0))},children:[m,(0,p.jsx)(xe.N,{lazy:!1,collapsed:i,onCollapseTransitionEnd:e=>{l(e),u(!e)},children:(0,p.jsx)("div",{className:ve,children:t})})]})}const we="details_b_Ee";function Ce({...e}){return(0,p.jsx)(Ae,{...e,className:(0,o.A)("alert alert--info",we,e.className)})}function ke(e){const t=s.Children.toArray(e.children),n=t.find((e=>s.isValidElement(e)&&"summary"===e.type)),a=(0,p.jsx)(p.Fragment,{children:t.filter((e=>e!==n))});return(0,p.jsx)(Ce,{...e,summary:n,children:a})}var Be=n(1107);function Ee(e){return(0,p.jsx)(Be.A,{...e})}const Le="containsTaskList_mC6p";function Te(e){if(void 0!==e)return(0,o.A)(e,e?.includes("contains-task-list")&&Le)}const _e="img_ev3q";var Me=n(7293),Se=n(418);const Ue={Head:r.A,details:ke,Details:ke,code:function(e){return function(e){return void 0!==e.children&&s.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")))}(e)?(0,p.jsx)(fe,{...e}):(0,p.jsx)(he,{...e})},a:function(e){return(0,p.jsx)(pe.A,{...e})},pre:function(e){return(0,p.jsx)(p.Fragment,{children:e.children})},ul:function(e){return(0,p.jsx)("ul",{...e,className:Te(e.className)})},li:function(e){return(0,ge.A)().collectAnchor(e.id),(0,p.jsx)("li",{...e})},img:function(e){return(0,p.jsx)("img",{decoding:"async",loading:"lazy",...e,className:(t=e.className,(0,o.A)(t,_e))});var t},h1:e=>(0,p.jsx)(Ee,{as:"h1",...e}),h2:e=>(0,p.jsx)(Ee,{as:"h2",...e}),h3:e=>(0,p.jsx)(Ee,{as:"h3",...e}),h4:e=>(0,p.jsx)(Ee,{as:"h4",...e}),h5:e=>(0,p.jsx)(Ee,{as:"h5",...e}),h6:e=>(0,p.jsx)(Ee,{as:"h6",...e}),admonition:Me.A,mermaid:Se.A};function ze({children:e}){return(0,p.jsx)(a.x,{components:Ue,children:e})}},4336:(e,t,n)=>{"use strict";n.d(t,{A:()=>g});n(6540);var s=n(4164),a=n(1312),r=n(7559),c=n(8774);const o={iconEdit:"iconEdit_Z9Sw"};var i=n(4848);function l({className:e,...t}){return(0,i.jsx)("svg",{fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,s.A)(o.iconEdit,e),"aria-hidden":"true",...t,children:(0,i.jsx)("g",{children:(0,i.jsx)("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})})})}function d({editUrl:e}){return(0,i.jsxs)(c.A,{to:e,className:r.G.common.editThisPage,children:[(0,i.jsx)(l,{}),(0,i.jsx)(a.A,{id:"theme.common.editThisPage",description:"The link label to edit the current page",children:"Edit this page"})]})}var u=n(6266);function m({lastUpdatedAt:e}){const t=new Date(e),n=(0,u.i)({day:"numeric",month:"short",year:"numeric",timeZone:"UTC"}).format(t);return(0,i.jsx)(a.A,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:(0,i.jsx)("b",{children:(0,i.jsx)("time",{dateTime:t.toISOString(),itemProp:"dateModified",children:n})})},children:" on {date}"})}function h({lastUpdatedBy:e}){return(0,i.jsx)(a.A,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:(0,i.jsx)("b",{children:e})},children:" by {user}"})}function f({lastUpdatedAt:e,lastUpdatedBy:t}){return(0,i.jsxs)("span",{className:r.G.common.lastUpdated,children:[(0,i.jsx)(a.A,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:e?(0,i.jsx)(m,{lastUpdatedAt:e}):"",byUser:t?(0,i.jsx)(h,{lastUpdatedBy:t}):""},children:"Last updated{atDate}{byUser}"}),!1]})}const p={lastUpdated:"lastUpdated_JAkA"};function g({className:e,editUrl:t,lastUpdatedAt:n,lastUpdatedBy:a}){return(0,i.jsxs)("div",{className:(0,s.A)("row",e),children:[(0,i.jsx)("div",{className:"col",children:t&&(0,i.jsx)(d,{editUrl:t})}),(0,i.jsx)("div",{className:(0,s.A)("col",p.lastUpdated),children:(n||a)&&(0,i.jsx)(f,{lastUpdatedAt:n,lastUpdatedBy:a})})]})}},6266:(e,t,n)=>{"use strict";n.d(t,{i:()=>a});var s=n(4586);function a(e={}){const{i18n:{currentLocale:t}}=(0,s.A)(),n=function(){const{i18n:{currentLocale:e,localeConfigs:t}}=(0,s.A)();return t[e].calendar}();return new Intl.DateTimeFormat(t,{calendar:n,...e})}},7293:(e,t,n)=>{"use strict";n.d(t,{A:()=>M});var s=n(6540),a=n(4848);function r(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=s.Children.toArray(e),n=t.find((e=>s.isValidElement(e)&&"mdxAdmonitionTitle"===e.type)),r=t.filter((e=>e!==n)),c=n?.props.children;return{mdxAdmonitionTitle:c,rest:r.length>0?(0,a.jsx)(a.Fragment,{children:r}):null}}(e.children),r=e.title??t;return{...e,...r&&{title:r},children:n}}var c=n(4164),o=n(1312),i=n(7559);const l="admonition_xJq3",d="admonitionHeading_Gvgb",u="admonitionIcon_Rf37",m="admonitionContent_BuS1";function h({type:e,className:t,children:n}){return(0,a.jsx)("div",{className:(0,c.A)(i.G.common.admonition,i.G.common.admonitionType(e),l,t),children:n})}function f({icon:e,title:t}){return(0,a.jsxs)("div",{className:d,children:[(0,a.jsx)("span",{className:u,children:e}),t]})}function p({children:e}){return e?(0,a.jsx)("div",{className:m,children:e}):null}function g(e){const{type:t,icon:n,title:s,children:r,className:c}=e;return(0,a.jsxs)(h,{type:t,className:c,children:[s||n?(0,a.jsx)(f,{title:s,icon:n}):null,(0,a.jsx)(p,{children:r})]})}function x(e){return(0,a.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const j={icon:(0,a.jsx)(x,{}),title:(0,a.jsx)(o.A,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function b(e){return(0,a.jsx)(g,{...j,...e,className:(0,c.A)("alert alert--secondary",e.className),children:e.children})}function v(e){return(0,a.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const N={icon:(0,a.jsx)(v,{}),title:(0,a.jsx)(o.A,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function y(e){return(0,a.jsx)(g,{...N,...e,className:(0,c.A)("alert alert--success",e.className),children:e.children})}function A(e){return(0,a.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const w={icon:(0,a.jsx)(A,{}),title:(0,a.jsx)(o.A,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function C(e){return(0,a.jsx)(g,{...w,...e,className:(0,c.A)("alert alert--info",e.className),children:e.children})}function k(e){return(0,a.jsx)("svg",{viewBox:"0 0 16 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const B={icon:(0,a.jsx)(k,{}),title:(0,a.jsx)(o.A,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function E(e){return(0,a.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const L={icon:(0,a.jsx)(E,{}),title:(0,a.jsx)(o.A,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const T={icon:(0,a.jsx)(k,{}),title:(0,a.jsx)(o.A,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const _={...{note:b,tip:y,info:C,warning:function(e){return(0,a.jsx)(g,{...B,...e,className:(0,c.A)("alert alert--warning",e.className),children:e.children})},danger:function(e){return(0,a.jsx)(g,{...L,...e,className:(0,c.A)("alert alert--danger",e.className),children:e.children})}},...{secondary:e=>(0,a.jsx)(b,{title:"secondary",...e}),important:e=>(0,a.jsx)(C,{title:"important",...e}),success:e=>(0,a.jsx)(y,{title:"success",...e}),caution:function(e){return(0,a.jsx)(g,{...T,...e,className:(0,c.A)("alert alert--warning",e.className),children:e.children})}}};function M(e){const t=r(e),n=(s=t.type,_[s]||(console.warn(`No admonition component found for admonition type "${s}". Using Info as fallback.`),_.info));var s;return(0,a.jsx)(n,{...t})}},8426:(e,t)=>{function n(e){let t,n=[];for(let s of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(s))n.push(parseInt(s,10));else if(t=s.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,s,a,r]=t;if(s&&r){s=parseInt(s),r=parseInt(r);const e=s<r?1:-1;"-"!==a&&".."!==a&&"\u2025"!==a||(r+=e);for(let t=s;t!==r;t+=e)n.push(t)}}return n}t.default=n,e.exports=n},8453:(e,t,n)=>{"use strict";n.d(t,{R:()=>c,x:()=>o});var s=n(6540);const a={},r=s.createContext(a);function c(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/6875c492.72d20027.js b/docs/assets/js/6875c492.72d20027.js deleted file mode 100644 index 9a0b33af..00000000 --- a/docs/assets/js/6875c492.72d20027.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4813],{2053:(e,t,a)=>{a.d(t,{A:()=>o});a(6540);var n=a(4164),s=a(1312),i=a(6133);const r={tags:"tags_jXut",tag:"tag_QGVx"};var l=a(4848);function o({tags:e}){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("b",{children:(0,l.jsx)(s.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,l.jsx)("ul",{className:(0,n.A)(r.tags,"padding--none","margin-left--sm"),children:e.map((e=>(0,l.jsx)("li",{className:r.tag,children:(0,l.jsx)(i.A,{...e})},e.permalink)))})]})}},2234:(e,t,a)=>{a.d(t,{A:()=>c});a(6540);var n=a(4164),s=a(4084),i=a(7559),r=a(7293),l=a(4848);function o({className:e}){return(0,l.jsx)(r.A,{type:"caution",title:(0,l.jsx)(s.Rc,{}),className:(0,n.A)(e,i.G.common.unlistedBanner),children:(0,l.jsx)(s.Uh,{})})}function c(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(s.AE,{}),(0,l.jsx)(o,{...e})]})}},2907:(e,t,a)=>{a.d(t,{A:()=>B});a(6540);var n=a(4164),s=a(4096),i=a(4848);function r({children:e,className:t}){return(0,i.jsx)("article",{className:t,children:e})}var l=a(8774);const o={title:"title_f1Hy"};function c({className:e}){const{metadata:t,isBlogPostPage:a}=(0,s.e7)(),{permalink:r,title:c}=t,d=a?"h1":"h2";return(0,i.jsx)(d,{className:(0,n.A)(o.title,e),children:a?c:(0,i.jsx)(l.A,{to:r,children:c})})}var d=a(1312),g=a(5846),u=a(6266);const m={container:"container_mt6G"};function h({readingTime:e}){const t=function(){const{selectMessage:e}=(0,g.W)();return t=>{const a=Math.ceil(t);return e(a,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:a}))}}();return(0,i.jsx)(i.Fragment,{children:t(e)})}function p({date:e,formattedDate:t}){return(0,i.jsx)("time",{dateTime:e,children:t})}function x(){return(0,i.jsx)(i.Fragment,{children:" \xb7 "})}function j({className:e}){const{metadata:t}=(0,s.e7)(),{date:a,readingTime:r}=t,l=(0,u.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,i.jsxs)("div",{className:(0,n.A)(m.container,"margin-vert--md",e),children:[(0,i.jsx)(p,{date:a,formattedDate:(o=a,l.format(new Date(o)))}),void 0!==r&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(x,{}),(0,i.jsx)(h,{readingTime:r})]})]});var o}var b=a(6382);const A={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function f({className:e}){const{metadata:{authors:t},assets:a}=(0,s.e7)();if(0===t.length)return null;const r=t.every((({name:e})=>!e)),l=1===t.length;return(0,i.jsx)("div",{className:(0,n.A)("margin-top--md margin-bottom--sm",r?A.imageOnlyAuthorRow:"row",e),children:t.map(((e,t)=>(0,i.jsx)("div",{className:(0,n.A)(!r&&(l?"col col--12":"col col--6"),r?A.imageOnlyAuthorCol:A.authorCol),children:(0,i.jsx)(b.A,{author:{...e,imageURL:a.authorsImageUrls[t]??e.imageURL}})},t)))})}function v(){return(0,i.jsxs)("header",{children:[(0,i.jsx)(c,{}),(0,i.jsx)(j,{}),(0,i.jsx)(f,{})]})}var T=a(440),N=a(3253);function w({children:e,className:t}){const{isBlogPostPage:a}=(0,s.e7)();return(0,i.jsx)("div",{id:a?T.LU:void 0,className:(0,n.A)("markdown",t),children:(0,i.jsx)(N.A,{children:e})})}var _=a(7559),k=a(4336),y=a(2053);function P(){return(0,i.jsx)("b",{children:(0,i.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function R(e){const{blogPostTitle:t,...a}=e;return(0,i.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...a,children:(0,i.jsx)(P,{})})}function U(){const{metadata:e,isBlogPostPage:t}=(0,s.e7)(),{tags:a,title:r,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,g=!t&&o,u=a.length>0;if(!(u||g||l))return null;if(t){const e=!!(l||d||c);return(0,i.jsxs)("footer",{className:"docusaurus-mt-lg",children:[u&&(0,i.jsx)("div",{className:(0,n.A)("row","margin-top--sm",_.G.blog.blogFooterEditMetaRow),children:(0,i.jsx)("div",{className:"col",children:(0,i.jsx)(y.A,{tags:a})})}),e&&(0,i.jsx)(k.A,{className:(0,n.A)("margin-top--sm",_.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,i.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[u&&(0,i.jsx)("div",{className:(0,n.A)("col",{"col--9":g}),children:(0,i.jsx)(y.A,{tags:a})}),g&&(0,i.jsx)("div",{className:(0,n.A)("col text--right",{"col--3":u}),children:(0,i.jsx)(R,{blogPostTitle:r,to:e.permalink})})]})}function B({children:e,className:t}){const a=function(){const{isBlogPostPage:e}=(0,s.e7)();return e?void 0:"margin-bottom--xl"}();return(0,i.jsxs)(r,{className:(0,n.A)(a,t),children:[(0,i.jsx)(v,{}),(0,i.jsx)(w,{children:e}),(0,i.jsx)(U,{})]})}},3069:(e,t,a)=>{a.r(t),a.d(t,{default:()=>b});a(6540);var n=a(4164),s=a(1312),i=a(5500),r=a(7559),l=a(6461),o=a(8774),c=a(8027),d=a(7713),g=a(1463),u=a(3892),m=a(2234),h=a(1107),p=a(4848);function x({tag:e}){const t=(0,l.ZD)(e);return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(i.be,{title:t,description:e.description}),(0,p.jsx)(g.A,{tag:"blog_tags_posts"})]})}function j({tag:e,items:t,sidebar:a,listMetadata:n}){const i=(0,l.ZD)(e);return(0,p.jsxs)(c.A,{sidebar:a,children:[e.unlisted&&(0,p.jsx)(m.A,{}),(0,p.jsxs)("header",{className:"margin-bottom--xl",children:[(0,p.jsx)(h.A,{as:"h1",children:i}),e.description&&(0,p.jsx)("p",{children:e.description}),(0,p.jsx)(o.A,{href:e.allTagsPath,children:(0,p.jsx)(s.A,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page",children:"View All Tags"})})]}),(0,p.jsx)(u.A,{items:t}),(0,p.jsx)(d.A,{metadata:n})]})}function b(e){return(0,p.jsxs)(i.e3,{className:(0,n.A)(r.G.wrapper.blogPages,r.G.page.blogTagPostListPage),children:[(0,p.jsx)(x,{...e}),(0,p.jsx)(j,{...e})]})}},3892:(e,t,a)=>{a.d(t,{A:()=>r});a(6540);var n=a(4096),s=a(2907),i=a(4848);function r({items:e,component:t=s.A}){return(0,i.jsx)(i.Fragment,{children:e.map((({content:e})=>(0,i.jsx)(n.in,{content:e,children:(0,i.jsx)(t,{children:(0,i.jsx)(e,{})})},e.metadata.permalink)))})}},4084:(e,t,a)=>{a.d(t,{AE:()=>o,Rc:()=>r,TT:()=>d,Uh:()=>l,Yh:()=>c});a(6540);var n=a(1312),s=a(5260),i=a(4848);function r(){return(0,i.jsx)(n.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,i.jsx)(n.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function o(){return(0,i.jsx)(s.A,{children:(0,i.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,i.jsx)(n.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,i.jsx)(n.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}},6133:(e,t,a)=>{a.d(t,{A:()=>l});a(6540);var n=a(4164),s=a(8774);const i={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var r=a(4848);function l({permalink:e,label:t,count:a,description:l}){return(0,r.jsxs)(s.A,{rel:"tag",href:e,title:l,className:(0,n.A)(i.tag,a?i.tagWithCount:i.tagRegular),children:[t,a&&(0,r.jsx)("span",{children:a})]})}},6461:(e,t,a)=>{a.d(t,{ZD:()=>r,uz:()=>l});a(6540);var n=a(1312),s=a(5846);a(4848);function i(){const{selectMessage:e}=(0,s.W)();return t=>e(t,(0,n.T)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:t}))}function r(e){const t=i();return(0,n.T)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:t(e.count),tagName:e.label})}const l=()=>(0,n.T)({id:"theme.blog.authorsList.pageTitle",message:"Authors",description:"The title of the authors page"})},7713:(e,t,a)=>{a.d(t,{A:()=>r});a(6540);var n=a(1312),s=a(9022),i=a(4848);function r(e){const{metadata:t}=e,{previousPage:a,nextPage:r}=t;return(0,i.jsxs)("nav",{className:"pagination-nav","aria-label":(0,n.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[a&&(0,i.jsx)(s.A,{permalink:a,title:(0,i.jsx)(n.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer entries"})}),r&&(0,i.jsx)(s.A,{permalink:r,title:(0,i.jsx)(n.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older entries"}),isNext:!0})]})}},9022:(e,t,a)=>{a.d(t,{A:()=>r});a(6540);var n=a(4164),s=a(8774),i=a(4848);function r(e){const{permalink:t,title:a,subLabel:r,isNext:l}=e;return(0,i.jsxs)(s.A,{className:(0,n.A)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[r&&(0,i.jsx)("div",{className:"pagination-nav__sublabel",children:r}),(0,i.jsx)("div",{className:"pagination-nav__label",children:a})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/6875c492.7e263e94.js b/docs/assets/js/6875c492.7e263e94.js new file mode 100644 index 00000000..c512db9e --- /dev/null +++ b/docs/assets/js/6875c492.7e263e94.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4813],{2053:(e,t,a)=>{a.d(t,{A:()=>o});a(6540);var n=a(4164),s=a(1312),i=a(6133);const r={tags:"tags_jXut",tag:"tag_QGVx"};var l=a(4848);function o({tags:e}){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("b",{children:(0,l.jsx)(s.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,l.jsx)("ul",{className:(0,n.A)(r.tags,"padding--none","margin-left--sm"),children:e.map(e=>(0,l.jsx)("li",{className:r.tag,children:(0,l.jsx)(i.A,{...e})},e.permalink))})]})}},2234:(e,t,a)=>{a.d(t,{A:()=>c});a(6540);var n=a(4164),s=a(7559),i=a(4084),r=a(7293),l=a(4848);function o({className:e}){return(0,l.jsx)(r.A,{type:"caution",title:(0,l.jsx)(i.Rc,{}),className:(0,n.A)(e,s.G.common.unlistedBanner),children:(0,l.jsx)(i.Uh,{})})}function c(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(i.AE,{}),(0,l.jsx)(o,{...e})]})}},2907:(e,t,a)=>{a.d(t,{A:()=>B});a(6540);var n=a(4164),s=a(4096),i=a(4848);function r({children:e,className:t}){return(0,i.jsx)("article",{className:t,children:e})}var l=a(8774);const o={title:"title_f1Hy"};function c({className:e}){const{metadata:t,isBlogPostPage:a}=(0,s.e7)(),{permalink:r,title:c}=t,d=a?"h1":"h2";return(0,i.jsx)(d,{className:(0,n.A)(o.title,e),children:a?c:(0,i.jsx)(l.A,{to:r,children:c})})}var d=a(1312),g=a(5846),u=a(6266);const m={container:"container_mt6G"};function h({readingTime:e}){const t=function(){const{selectMessage:e}=(0,g.W)();return t=>{const a=Math.ceil(t);return e(a,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:a}))}}();return(0,i.jsx)(i.Fragment,{children:t(e)})}function p({date:e,formattedDate:t}){return(0,i.jsx)("time",{dateTime:e,children:t})}function x(){return(0,i.jsx)(i.Fragment,{children:" \xb7 "})}function j({className:e}){const{metadata:t}=(0,s.e7)(),{date:a,readingTime:r}=t,l=(0,u.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,i.jsxs)("div",{className:(0,n.A)(m.container,"margin-vert--md",e),children:[(0,i.jsx)(p,{date:a,formattedDate:(o=a,l.format(new Date(o)))}),void 0!==r&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(x,{}),(0,i.jsx)(h,{readingTime:r})]})]});var o}var b=a(6382);const A={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function f({className:e}){const{metadata:{authors:t},assets:a}=(0,s.e7)();if(0===t.length)return null;const r=t.every(({name:e})=>!e),l=1===t.length;return(0,i.jsx)("div",{className:(0,n.A)("margin-top--md margin-bottom--sm",r?A.imageOnlyAuthorRow:"row",e),children:t.map((e,t)=>(0,i.jsx)("div",{className:(0,n.A)(!r&&(l?"col col--12":"col col--6"),r?A.imageOnlyAuthorCol:A.authorCol),children:(0,i.jsx)(b.A,{author:{...e,imageURL:a.authorsImageUrls[t]??e.imageURL}})},t))})}function v(){return(0,i.jsxs)("header",{children:[(0,i.jsx)(c,{}),(0,i.jsx)(j,{}),(0,i.jsx)(f,{})]})}var T=a(440),N=a(3253);function w({children:e,className:t}){const{isBlogPostPage:a}=(0,s.e7)();return(0,i.jsx)("div",{id:a?T.LU:void 0,className:(0,n.A)("markdown",t),children:(0,i.jsx)(N.A,{children:e})})}var _=a(7559),k=a(4336),y=a(2053);function P(){return(0,i.jsx)("b",{children:(0,i.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function R(e){const{blogPostTitle:t,...a}=e;return(0,i.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...a,children:(0,i.jsx)(P,{})})}function U(){const{metadata:e,isBlogPostPage:t}=(0,s.e7)(),{tags:a,title:r,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,g=!t&&o,u=a.length>0;if(!(u||g||l))return null;if(t){const e=!!(l||d||c);return(0,i.jsxs)("footer",{className:"docusaurus-mt-lg",children:[u&&(0,i.jsx)("div",{className:(0,n.A)("row","margin-top--sm",_.G.blog.blogFooterEditMetaRow),children:(0,i.jsx)("div",{className:"col",children:(0,i.jsx)(y.A,{tags:a})})}),e&&(0,i.jsx)(k.A,{className:(0,n.A)("margin-top--sm",_.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,i.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[u&&(0,i.jsx)("div",{className:(0,n.A)("col",{"col--9":g}),children:(0,i.jsx)(y.A,{tags:a})}),g&&(0,i.jsx)("div",{className:(0,n.A)("col text--right",{"col--3":u}),children:(0,i.jsx)(R,{blogPostTitle:r,to:e.permalink})})]})}function B({children:e,className:t}){const a=function(){const{isBlogPostPage:e}=(0,s.e7)();return e?void 0:"margin-bottom--xl"}();return(0,i.jsxs)(r,{className:(0,n.A)(a,t),children:[(0,i.jsx)(v,{}),(0,i.jsx)(w,{children:e}),(0,i.jsx)(U,{})]})}},3069:(e,t,a)=>{a.r(t),a.d(t,{default:()=>b});a(6540);var n=a(4164),s=a(1312),i=a(7559),r=a(5500),l=a(6461),o=a(8774),c=a(8027),d=a(7713),g=a(1463),u=a(3892),m=a(2234),h=a(1107),p=a(4848);function x({tag:e}){const t=(0,l.ZD)(e);return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(r.be,{title:t,description:e.description}),(0,p.jsx)(g.A,{tag:"blog_tags_posts"})]})}function j({tag:e,items:t,sidebar:a,listMetadata:n}){const i=(0,l.ZD)(e);return(0,p.jsxs)(c.A,{sidebar:a,children:[e.unlisted&&(0,p.jsx)(m.A,{}),(0,p.jsxs)("header",{className:"margin-bottom--xl",children:[(0,p.jsx)(h.A,{as:"h1",children:i}),e.description&&(0,p.jsx)("p",{children:e.description}),(0,p.jsx)(o.A,{href:e.allTagsPath,children:(0,p.jsx)(s.A,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page",children:"View All Tags"})})]}),(0,p.jsx)(u.A,{items:t}),(0,p.jsx)(d.A,{metadata:n})]})}function b(e){return(0,p.jsxs)(r.e3,{className:(0,n.A)(i.G.wrapper.blogPages,i.G.page.blogTagPostListPage),children:[(0,p.jsx)(x,{...e}),(0,p.jsx)(j,{...e})]})}},3892:(e,t,a)=>{a.d(t,{A:()=>r});a(6540);var n=a(4096),s=a(2907),i=a(4848);function r({items:e,component:t=s.A}){return(0,i.jsx)(i.Fragment,{children:e.map(({content:e})=>(0,i.jsx)(n.in,{content:e,children:(0,i.jsx)(t,{children:(0,i.jsx)(e,{})})},e.metadata.permalink))})}},4084:(e,t,a)=>{a.d(t,{AE:()=>o,Rc:()=>r,TT:()=>d,Uh:()=>l,Yh:()=>c});a(6540);var n=a(1312),s=a(5260),i=a(4848);function r(){return(0,i.jsx)(n.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,i.jsx)(n.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function o(){return(0,i.jsx)(s.A,{children:(0,i.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,i.jsx)(n.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,i.jsx)(n.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}},6133:(e,t,a)=>{a.d(t,{A:()=>l});a(6540);var n=a(4164),s=a(8774);const i={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var r=a(4848);function l({permalink:e,label:t,count:a,description:l}){return(0,r.jsxs)(s.A,{rel:"tag",href:e,title:l,className:(0,n.A)(i.tag,a?i.tagWithCount:i.tagRegular),children:[t,a&&(0,r.jsx)("span",{children:a})]})}},6461:(e,t,a)=>{a.d(t,{ZD:()=>r,uz:()=>l});a(6540);var n=a(1312),s=a(5846);a(4848);function i(){const{selectMessage:e}=(0,s.W)();return t=>e(t,(0,n.T)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:t}))}function r(e){const t=i();return(0,n.T)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:t(e.count),tagName:e.label})}const l=()=>(0,n.T)({id:"theme.blog.authorsList.pageTitle",message:"Authors",description:"The title of the authors page"})},7713:(e,t,a)=>{a.d(t,{A:()=>r});a(6540);var n=a(1312),s=a(9022),i=a(4848);function r(e){const{metadata:t}=e,{previousPage:a,nextPage:r}=t;return(0,i.jsxs)("nav",{className:"pagination-nav","aria-label":(0,n.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[a&&(0,i.jsx)(s.A,{permalink:a,title:(0,i.jsx)(n.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer entries"})}),r&&(0,i.jsx)(s.A,{permalink:r,title:(0,i.jsx)(n.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older entries"}),isNext:!0})]})}},9022:(e,t,a)=>{a.d(t,{A:()=>r});a(6540);var n=a(4164),s=a(8774),i=a(4848);function r(e){const{permalink:t,title:a,subLabel:r,isNext:l}=e;return(0,i.jsxs)(s.A,{className:(0,n.A)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[r&&(0,i.jsx)("div",{className:"pagination-nav__sublabel",children:r}),(0,i.jsx)("div",{className:"pagination-nav__label",children:a})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/6bb91276.d5be09e8.js b/docs/assets/js/6bb91276.d5be09e8.js new file mode 100644 index 00000000..ae68881c --- /dev/null +++ b/docs/assets/js/6bb91276.d5be09e8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9226],{8758:a=>{a.exports=JSON.parse('{"tag":{"label":"vllm","permalink":"/BharatMLStack/blog/tags/vllm","allTagsPath":"/BharatMLStack/blog/tags","count":2,"unlisted":false},"listMetadata":{"permalink":"/BharatMLStack/blog/tags/vllm","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/72dc5b25.20421ae4.js b/docs/assets/js/72dc5b25.20421ae4.js new file mode 100644 index 00000000..f6c3affa --- /dev/null +++ b/docs/assets/js/72dc5b25.20421ae4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8261],{3613:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"v1.0.0","description":"Numerix v1.0.0","slug":"/online-feature-store/v1.0.0","permalink":"/BharatMLStack/online-feature-store/v1.0.0","sidebar":"tutorialSidebar","navigation":{"previous":{"title":"Online Feature Store","permalink":"/BharatMLStack/category/online-feature-store"},"next":{"title":"Architecture","permalink":"/BharatMLStack/online-feature-store/v1.0.0/architecture"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/72dc5b25.e57720a7.js b/docs/assets/js/72dc5b25.e57720a7.js deleted file mode 100644 index 5c7514b9..00000000 --- a/docs/assets/js/72dc5b25.e57720a7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8261],{3613:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"v1.0.0","description":"Python SDK v1.0.0 documentation for BharatML Stack. Contains API reference, usage guides, and examples for the Python client libraries including gRPC feature client, Spark feature push client, and common utilities.","slug":"/online-feature-store/v1.0.0","permalink":"/BharatMLStack/online-feature-store/v1.0.0","sidebar":"tutorialSidebar","navigation":{"previous":{"title":"Online Feature Store","permalink":"/BharatMLStack/category/online-feature-store"},"next":{"title":"Architecture","permalink":"/BharatMLStack/online-feature-store/v1.0.0/architecture"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/7518.6ac3b679.js b/docs/assets/js/7518.6ac3b679.js deleted file mode 100644 index c86683c0..00000000 --- a/docs/assets/js/7518.6ac3b679.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7518],{4096:(e,t,s)=>{s.d(t,{in:()=>c,OU:()=>A,Ki:()=>k,kJ:()=>f,x:()=>l,e7:()=>h,J_:()=>p,Gx:()=>N});var a=s(6540),n=s(9532),i=s(6803),r=s(4848);function l(){const e=(0,i.A)(),t=e?.data?.blogMetadata;if(!t)throw new Error("useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context");return t}const o=a.createContext(null);function c({children:e,content:t,isBlogPostPage:s=!1}){const n=function({content:e,isBlogPostPage:t}){return(0,a.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,toc:e.toc,isBlogPostPage:t})),[e,t])}({content:t,isBlogPostPage:s});return(0,r.jsx)(o.Provider,{value:n,children:e})}function h(){const e=(0,a.useContext)(o);if(null===e)throw new n.dV("BlogPostProvider");return e}var m=s(6025),u=s(4586);const d=e=>new Date(e).toISOString();function g(e){const t=e.map(v);return{author:1===t.length?t[0]:t}}function x(e,t,s){return e?{image:w({imageUrl:t(e,{absolute:!0}),caption:`title image for the blog post: ${s}`})}:{}}function f(e){const{siteConfig:t}=(0,u.A)(),{withBaseUrl:s}=(0,m.hH)(),{metadata:{blogDescription:a,blogTitle:n,permalink:i}}=e,r=`${t.url}${i}`;return{"@context":"https://schema.org","@type":"Blog","@id":r,mainEntityOfPage:r,headline:n,description:a,blogPost:e.items.map((e=>function(e,t,s){const{assets:a,frontMatter:n,metadata:i}=e,{date:r,title:l,description:o,lastUpdatedAt:c}=i,h=a.image??n.image,m=n.keywords??[],u=`${t.url}${i.permalink}`,f=c?d(c):void 0;return{"@type":"BlogPosting","@id":u,mainEntityOfPage:u,url:u,headline:l,name:l,description:o,datePublished:r,...f?{dateModified:f}:{},...g(i.authors),...x(h,s,l),...m?{keywords:m}:{}}}(e.content,t,s)))}}function p(){const e=l(),{assets:t,metadata:s}=h(),{siteConfig:a}=(0,u.A)(),{withBaseUrl:n}=(0,m.hH)(),{date:i,title:r,description:o,frontMatter:c,lastUpdatedAt:f}=s,p=t.image??c.image,v=c.keywords??[],w=f?d(f):void 0,j=`${a.url}${s.permalink}`;return{"@context":"https://schema.org","@type":"BlogPosting","@id":j,mainEntityOfPage:j,url:j,headline:r,name:r,description:o,datePublished:i,...w?{dateModified:w}:{},...g(s.authors),...x(p,n,r),...v?{keywords:v}:{},isPartOf:{"@type":"Blog","@id":`${a.url}${e.blogBasePath}`,name:e.blogTitle}}}function v(e){return{"@type":"Person",...e.name?{name:e.name}:{},...e.title?{description:e.title}:{},...e.url?{url:e.url}:{},...e.email?{email:e.email}:{},...e.imageURL?{image:e.imageURL}:{}}}function w({imageUrl:e,caption:t}){return{"@type":"ImageObject","@id":e,url:e,contentUrl:e,caption:t}}var j=s(6347),b=s(8774),C=s(1682),M=s(9169);function N(e){const{pathname:t}=(0,j.zy)();return(0,a.useMemo)((()=>e.filter((e=>function(e,t){return!(e.unlisted&&!(0,M.ys)(e.permalink,t))}(e,t)))),[e,t])}function k(e){const t=(0,C.$z)(e,(e=>`${new Date(e.date).getFullYear()}`)),s=Object.entries(t);return s.reverse(),s}function A({items:e,ulClassName:t,liClassName:s,linkClassName:a,linkActiveClassName:n}){return(0,r.jsx)("ul",{className:t,children:e.map((e=>(0,r.jsx)("li",{className:s,children:(0,r.jsx)(b.A,{isNavLink:!0,to:e.permalink,className:a,activeClassName:n,children:e.title})},e.permalink)))})}},5846:(e,t,s)=>{s.d(t,{W:()=>c});var a=s(6540),n=s(4586);const i=["zero","one","two","few","many","other"];function r(e){return i.filter((t=>e.includes(t)))}const l={locale:"en",pluralForms:r(["one","other"]),select:e=>1===e?"one":"other"};function o(){const{i18n:{currentLocale:e}}=(0,n.A)();return(0,a.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:r(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),l}}),[e])}function c(){const e=o();return{selectMessage:(t,s)=>function(e,t,s){const a=e.split("|");if(1===a.length)return a[0];a.length>s.pluralForms.length&&console.error(`For locale=${s.locale}, a maximum of ${s.pluralForms.length} plural forms are expected (${s.pluralForms.join(",")}), but the message contains ${a.length}: ${e}`);const n=s.select(t),i=s.pluralForms.indexOf(n);return a[Math.min(i,a.length-1)]}(s,t,e)}}},6382:(e,t,s)=>{s.d(t,{A:()=>C});var a=s(6540),n=s(4164),i=s(8774),r=s(4848);const l="githubSvg_Uu4N";const o="xSvg_y3PF";const c=function(e){return(0,r.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...e,children:[(0,r.jsx)("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),(0,r.jsx)("path",{d:"M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0"}),(0,r.jsx)("path",{d:"M3.6 9h16.8"}),(0,r.jsx)("path",{d:"M3.6 15h16.8"}),(0,r.jsx)("path",{d:"M11.5 3a17 17 0 0 0 0 18"}),(0,r.jsx)("path",{d:"M12.5 3a17 17 0 0 1 0 18"})]})};const h="instagramSvg_YC40";const m="threadsSvg_PTXY";const u={authorSocials:"authorSocials_rSDt",authorSocialLink:"authorSocialLink_owbf",authorSocialIcon:"authorSocialIcon_XYv3"},d={twitter:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 209",width:"1em",height:"1em",preserveAspectRatio:"xMidYMid",...e,children:(0,r.jsx)("path",{d:"M256 25.45c-9.42 4.177-19.542 7-30.166 8.27 10.845-6.5 19.172-16.793 23.093-29.057a105.183 105.183 0 0 1-33.351 12.745C205.995 7.201 192.346.822 177.239.822c-29.006 0-52.523 23.516-52.523 52.52 0 4.117.465 8.125 1.36 11.97-43.65-2.191-82.35-23.1-108.255-54.876-4.52 7.757-7.11 16.78-7.11 26.404 0 18.222 9.273 34.297 23.365 43.716a52.312 52.312 0 0 1-23.79-6.57c-.003.22-.003.44-.003.661 0 25.447 18.104 46.675 42.13 51.5a52.592 52.592 0 0 1-23.718.9c6.683 20.866 26.08 36.05 49.062 36.475-17.975 14.086-40.622 22.483-65.228 22.483-4.24 0-8.42-.249-12.529-.734 23.243 14.902 50.85 23.597 80.51 23.597 96.607 0 149.434-80.031 149.434-149.435 0-2.278-.05-4.543-.152-6.795A106.748 106.748 0 0 0 256 25.45",fill:"#55acee"})})},label:"Twitter"},github:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 256 250",preserveAspectRatio:"xMidYMid",style:{"--dark":"#000","--light":"#fff"},...e,className:(0,n.A)(e.className,l),children:(0,r.jsx)("path",{d:"M128.001 0C57.317 0 0 57.307 0 128.001c0 56.554 36.676 104.535 87.535 121.46 6.397 1.185 8.746-2.777 8.746-6.158 0-3.052-.12-13.135-.174-23.83-35.61 7.742-43.124-15.103-43.124-15.103-5.823-14.795-14.213-18.73-14.213-18.73-11.613-7.944.876-7.78.876-7.78 12.853.902 19.621 13.19 19.621 13.19 11.417 19.568 29.945 13.911 37.249 10.64 1.149-8.272 4.466-13.92 8.127-17.116-28.431-3.236-58.318-14.212-58.318-63.258 0-13.975 5-25.394 13.188-34.358-1.329-3.224-5.71-16.242 1.24-33.874 0 0 10.749-3.44 35.21 13.121 10.21-2.836 21.16-4.258 32.038-4.307 10.878.049 21.837 1.47 32.066 4.307 24.431-16.56 35.165-13.12 35.165-13.12 6.967 17.63 2.584 30.65 1.255 33.873 8.207 8.964 13.173 20.383 13.173 34.358 0 49.163-29.944 59.988-58.447 63.157 4.591 3.972 8.682 11.762 8.682 23.704 0 17.126-.148 30.91-.148 35.126 0 3.407 2.304 7.398 8.792 6.14C219.37 232.5 256 184.537 256 128.002 256 57.307 198.691 0 128.001 0Zm-80.06 182.34c-.282.636-1.283.827-2.194.39-.929-.417-1.45-1.284-1.15-1.922.276-.655 1.279-.838 2.205-.399.93.418 1.46 1.293 1.139 1.931Zm6.296 5.618c-.61.566-1.804.303-2.614-.591-.837-.892-.994-2.086-.375-2.66.63-.566 1.787-.301 2.626.591.838.903 1 2.088.363 2.66Zm4.32 7.188c-.785.545-2.067.034-2.86-1.104-.784-1.138-.784-2.503.017-3.05.795-.547 2.058-.055 2.861 1.075.782 1.157.782 2.522-.019 3.08Zm7.304 8.325c-.701.774-2.196.566-3.29-.49-1.119-1.032-1.43-2.496-.726-3.27.71-.776 2.213-.558 3.315.49 1.11 1.03 1.45 2.505.701 3.27Zm9.442 2.81c-.31 1.003-1.75 1.459-3.199 1.033-1.448-.439-2.395-1.613-2.103-2.626.301-1.01 1.747-1.484 3.207-1.028 1.446.436 2.396 1.602 2.095 2.622Zm10.744 1.193c.036 1.055-1.193 1.93-2.715 1.95-1.53.034-2.769-.82-2.786-1.86 0-1.065 1.202-1.932 2.733-1.958 1.522-.03 2.768.818 2.768 1.868Zm10.555-.405c.182 1.03-.875 2.088-2.387 2.37-1.485.271-2.861-.365-3.05-1.386-.184-1.056.893-2.114 2.376-2.387 1.514-.263 2.868.356 3.061 1.403Z"})})},label:"GitHub"},stackoverflow:{Icon:function(e){return(0,r.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 169.61 200",width:"1em",height:"1em",...e,children:[(0,r.jsx)("path",{d:"M140.44 178.38v-48.65h21.61V200H0v-70.27h21.61v48.65z",fill:"#bcbbbb"}),(0,r.jsx)("path",{d:"M124.24 140.54l4.32-16.22-86.97-17.83-3.78 17.83zM49.7 82.16L130.72 120l7.56-16.22-81.02-37.83zm22.68-40l68.06 57.3 11.35-13.51-68.6-57.3-11.35 13.51zM116.14 0l-14.59 10.81 53.48 71.89 14.58-10.81zM37.81 162.16h86.43v-16.21H37.81z",fill:"#f48024"})]})},label:"Stack Overflow"},linkedin:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",preserveAspectRatio:"xMidYMid",viewBox:"0 0 256 256",...e,children:(0,r.jsx)("path",{d:"M218.123 218.127h-37.931v-59.403c0-14.165-.253-32.4-19.728-32.4-19.756 0-22.779 15.434-22.779 31.369v60.43h-37.93V95.967h36.413v16.694h.51a39.907 39.907 0 0 1 35.928-19.733c38.445 0 45.533 25.288 45.533 58.186l-.016 67.013ZM56.955 79.27c-12.157.002-22.014-9.852-22.016-22.009-.002-12.157 9.851-22.014 22.008-22.016 12.157-.003 22.014 9.851 22.016 22.008A22.013 22.013 0 0 1 56.955 79.27m18.966 138.858H37.95V95.967h37.97v122.16ZM237.033.018H18.89C8.58-.098.125 8.161-.001 18.471v219.053c.122 10.315 8.576 18.582 18.89 18.474h218.144c10.336.128 18.823-8.139 18.966-18.474V18.454c-.147-10.33-8.635-18.588-18.966-18.453",fill:"#0A66C2"})})},label:"LinkedIn"},x:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",fill:"none",viewBox:"0 0 1200 1227",style:{"--dark":"#000","--light":"#fff"},...e,className:(0,n.A)(e.className,o),children:(0,r.jsx)("path",{d:"M714.163 519.284 1160.89 0h-105.86L667.137 450.887 357.328 0H0l468.492 681.821L0 1226.37h105.866l409.625-476.152 327.181 476.152H1200L714.137 519.284h.026ZM569.165 687.828l-47.468-67.894-377.686-540.24h162.604l304.797 435.991 47.468 67.894 396.2 566.721H892.476L569.165 687.854v-.026Z"})})},label:"X"},bluesky:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",preserveAspectRatio:"xMidYMid",viewBox:"0 0 256 226",...e,children:(0,r.jsx)("path",{fill:"#1185FE",d:"M55.491 15.172c29.35 22.035 60.917 66.712 72.509 90.686 11.592-23.974 43.159-68.651 72.509-90.686C221.686-.727 256-13.028 256 26.116c0 7.818-4.482 65.674-7.111 75.068-9.138 32.654-42.436 40.983-72.057 35.942 51.775 8.812 64.946 38 36.501 67.187-54.021 55.433-77.644-13.908-83.696-31.676-1.11-3.257-1.63-4.78-1.637-3.485-.008-1.296-.527.228-1.637 3.485-6.052 17.768-29.675 87.11-83.696 31.676-28.445-29.187-15.274-58.375 36.5-67.187-29.62 5.041-62.918-3.288-72.056-35.942C4.482 91.79 0 33.934 0 26.116 0-13.028 34.314-.727 55.491 15.172Z"})})},label:"Bluesky"},instagram:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",preserveAspectRatio:"xMidYMid",viewBox:"0 0 256 256",style:{"--dark":"#000","--light":"#fff"},...e,className:(0,n.A)(e.className,h),children:(0,r.jsx)("path",{d:"M128 23.064c34.177 0 38.225.13 51.722.745 12.48.57 19.258 2.655 23.769 4.408 5.974 2.322 10.238 5.096 14.717 9.575 4.48 4.479 7.253 8.743 9.575 14.717 1.753 4.511 3.838 11.289 4.408 23.768.615 13.498.745 17.546.745 51.723 0 34.178-.13 38.226-.745 51.723-.57 12.48-2.655 19.257-4.408 23.768-2.322 5.974-5.096 10.239-9.575 14.718-4.479 4.479-8.743 7.253-14.717 9.574-4.511 1.753-11.289 3.839-23.769 4.408-13.495.616-17.543.746-51.722.746-34.18 0-38.228-.13-51.723-.746-12.48-.57-19.257-2.655-23.768-4.408-5.974-2.321-10.239-5.095-14.718-9.574-4.479-4.48-7.253-8.744-9.574-14.718-1.753-4.51-3.839-11.288-4.408-23.768-.616-13.497-.746-17.545-.746-51.723 0-34.177.13-38.225.746-51.722.57-12.48 2.655-19.258 4.408-23.769 2.321-5.974 5.095-10.238 9.574-14.717 4.48-4.48 8.744-7.253 14.718-9.575 4.51-1.753 11.288-3.838 23.768-4.408 13.497-.615 17.545-.745 51.723-.745M128 0C93.237 0 88.878.147 75.226.77c-13.625.622-22.93 2.786-31.071 5.95-8.418 3.271-15.556 7.648-22.672 14.764C14.367 28.6 9.991 35.738 6.72 44.155 3.555 52.297 1.392 61.602.77 75.226.147 88.878 0 93.237 0 128c0 34.763.147 39.122.77 52.774.622 13.625 2.785 22.93 5.95 31.071 3.27 8.417 7.647 15.556 14.763 22.672 7.116 7.116 14.254 11.492 22.672 14.763 8.142 3.165 17.446 5.328 31.07 5.95 13.653.623 18.012.77 52.775.77s39.122-.147 52.774-.77c13.624-.622 22.929-2.785 31.07-5.95 8.418-3.27 15.556-7.647 22.672-14.763 7.116-7.116 11.493-14.254 14.764-22.672 3.164-8.142 5.328-17.446 5.95-31.07.623-13.653.77-18.012.77-52.775s-.147-39.122-.77-52.774c-.622-13.624-2.786-22.929-5.95-31.07-3.271-8.418-7.648-15.556-14.764-22.672C227.4 14.368 220.262 9.99 211.845 6.72c-8.142-3.164-17.447-5.328-31.071-5.95C167.122.147 162.763 0 128 0Zm0 62.27C91.698 62.27 62.27 91.7 62.27 128c0 36.302 29.428 65.73 65.73 65.73 36.301 0 65.73-29.428 65.73-65.73 0-36.301-29.429-65.73-65.73-65.73Zm0 108.397c-23.564 0-42.667-19.103-42.667-42.667S104.436 85.333 128 85.333s42.667 19.103 42.667 42.667-19.103 42.667-42.667 42.667Zm83.686-110.994c0 8.484-6.876 15.36-15.36 15.36-8.483 0-15.36-6.876-15.36-15.36 0-8.483 6.877-15.36 15.36-15.36 8.484 0 15.36 6.877 15.36 15.36Z"})})},label:"Instagram"},threads:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg","aria-label":"Threads",viewBox:"0 0 192 192",width:"1em",fill:"none",height:"1em",style:{"--dark":"#000","--light":"#fff"},...e,className:(0,n.A)(e.className,m),children:(0,r.jsx)("path",{d:"M141.537 88.988a66.667 66.667 0 0 0-2.518-1.143c-1.482-27.307-16.403-42.94-41.457-43.1h-.34c-14.986 0-27.449 6.396-35.12 18.036l13.779 9.452c5.73-8.695 14.724-10.548 21.348-10.548h.229c8.249.053 14.474 2.452 18.503 7.129 2.932 3.405 4.893 8.111 5.864 14.05-7.314-1.243-15.224-1.626-23.68-1.14-23.82 1.371-39.134 15.264-38.105 34.568.522 9.792 5.4 18.216 13.735 23.719 7.047 4.652 16.124 6.927 25.557 6.412 12.458-.683 22.231-5.436 29.049-14.127 5.178-6.6 8.453-15.153 9.899-25.93 5.937 3.583 10.337 8.298 12.767 13.966 4.132 9.635 4.373 25.468-8.546 38.376-11.319 11.308-24.925 16.2-45.488 16.351-22.809-.169-40.06-7.484-51.275-21.742C35.236 139.966 29.808 120.682 29.605 96c.203-24.682 5.63-43.966 16.133-57.317C56.954 24.425 74.204 17.11 97.013 16.94c22.975.17 40.526 7.52 52.171 21.847 5.71 7.026 10.015 15.86 12.853 26.162l16.147-4.308c-3.44-12.68-8.853-23.606-16.219-32.668C147.036 9.607 125.202.195 97.07 0h-.113C68.882.194 47.292 9.642 32.788 28.08 19.882 44.485 13.224 67.315 13.001 95.932L13 96v.067c.224 28.617 6.882 51.447 19.788 67.854C47.292 182.358 68.882 191.806 96.957 192h.113c24.96-.173 42.554-6.708 57.048-21.189 18.963-18.945 18.392-42.692 12.142-57.27-4.484-10.454-13.033-18.945-24.723-24.553ZM98.44 129.507c-10.44.588-21.286-4.098-21.82-14.135-.397-7.442 5.296-15.746 22.461-16.735 1.966-.114 3.895-.169 5.79-.169 6.235 0 12.068.606 17.371 1.765-1.978 24.702-13.58 28.713-23.802 29.274Z"})})},label:"Threads"},mastodon:{Icon:function(e){const t=(0,a.useId)();return(0,r.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 61 65",width:"1em",height:"1em",...e,children:[(0,r.jsx)("path",{fill:`url(#${t})`,d:"M60.754 14.39C59.814 7.406 53.727 1.903 46.512.836 45.294.656 40.682 0 29.997 0h-.08C19.23 0 16.938.656 15.72.836 8.705 1.873 2.299 6.82.745 13.886c-.748 3.48-.828 7.338-.689 10.877.198 5.075.237 10.142.697 15.197a71.482 71.482 0 0 0 1.664 9.968c1.477 6.056 7.458 11.096 13.317 13.152a35.718 35.718 0 0 0 19.484 1.028 28.365 28.365 0 0 0 2.107-.576c1.572-.5 3.413-1.057 4.766-2.038a.154.154 0 0 0 .062-.118v-4.899a.146.146 0 0 0-.055-.111.145.145 0 0 0-.122-.028 54 54 0 0 1-12.644 1.478c-7.328 0-9.298-3.478-9.863-4.925a15.258 15.258 0 0 1-.857-3.882.142.142 0 0 1 .178-.145 52.976 52.976 0 0 0 12.437 1.477c1.007 0 2.012 0 3.02-.026 4.213-.119 8.654-.334 12.8-1.144.103-.02.206-.038.295-.065 6.539-1.255 12.762-5.196 13.394-15.176.024-.393.083-4.115.083-4.523.003-1.386.446-9.829-.065-15.017Z"}),(0,r.jsx)("path",{fill:"#fff",d:"M50.394 22.237v17.35H43.52V22.749c0-3.545-1.478-5.353-4.483-5.353-3.303 0-4.958 2.139-4.958 6.364v9.217h-6.835V23.76c0-4.225-1.657-6.364-4.96-6.364-2.988 0-4.48 1.808-4.48 5.353v16.84H10.93V22.237c0-3.545.905-6.362 2.715-8.45 1.868-2.082 4.317-3.152 7.358-3.152 3.519 0 6.178 1.354 7.951 4.057l1.711 2.871 1.714-2.871c1.773-2.704 4.432-4.056 7.945-4.056 3.038 0 5.487 1.069 7.36 3.152 1.81 2.085 2.712 4.902 2.71 8.449Z"}),(0,r.jsx)("defs",{children:(0,r.jsxs)("linearGradient",{id:t,x1:30.5,x2:30.5,y1:0,y2:65,gradientUnits:"userSpaceOnUse",children:[(0,r.jsx)("stop",{stopColor:"#6364FF"}),(0,r.jsx)("stop",{offset:1,stopColor:"#563ACC"})]})})]})},label:"Mastodon"},youtube:{Icon:function(e){return(0,r.jsxs)("svg",{viewBox:"0 0 256 180",width:"1em",height:"1em",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid",...e,children:[(0,r.jsx)("path",{d:"M250.346 28.075A32.18 32.18 0 0 0 227.69 5.418C207.824 0 127.87 0 127.87 0S47.912.164 28.046 5.582A32.18 32.18 0 0 0 5.39 28.24c-6.009 35.298-8.34 89.084.165 122.97a32.18 32.18 0 0 0 22.656 22.657c19.866 5.418 99.822 5.418 99.822 5.418s79.955 0 99.82-5.418a32.18 32.18 0 0 0 22.657-22.657c6.338-35.348 8.291-89.1-.164-123.134Z",fill:"red"}),(0,r.jsx)("path",{fill:"#FFF",d:"m102.421 128.06 66.328-38.418-66.328-38.418z"})]})},label:"YouTube"},twitch:{Icon:function(e){return(0,r.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",x:0,y:0,viewBox:"0 0 2400 2800",width:"1em",height:"1em",...e,children:[(0,r.jsx)("path",{d:"m2200 1300-400 400h-400l-350 350v-350H600V200h1600z",fill:"#fff"}),(0,r.jsxs)("g",{children:[(0,r.jsx)("path",{d:"M500 0 0 500v1800h600v500l500-500h400l900-900V0H500zm1700 1300-400 400h-400l-350 350v-350H600V200h1600v1100z",fill:"#9146ff"}),(0,r.jsx)("path",{d:"M1700 550h200v600h-200zM1150 550h200v600h-200z",fill:"#9146ff"})]})]})},label:"Twitch"}};function g({platform:e,link:t}){const{Icon:s,label:a}=d[l=e]??{Icon:c,label:l};var l;return(0,r.jsx)(i.A,{className:u.authorSocialLink,href:t,title:a,children:(0,r.jsx)(s,{className:(0,n.A)(u.authorSocialLink)})})}function x({author:e}){const t=Object.entries(e.socials??{});return(0,r.jsx)("div",{className:u.authorSocials,children:t.map((([e,t])=>(0,r.jsx)(g,{platform:e,link:t},e)))})}var f=s(1107);const p={authorImage:"authorImage_XqGP","author-as-h1":"author-as-h1_n9oJ","author-as-h2":"author-as-h2_gXvM",authorDetails:"authorDetails_lV9A",authorName:"authorName_yefp",authorTitle:"authorTitle_nd0D",authorBlogPostCount:"authorBlogPostCount_iiJ5"};function v(e){return e.href?(0,r.jsx)(i.A,{...e}):(0,r.jsx)(r.Fragment,{children:e.children})}function w({title:e}){return(0,r.jsx)("small",{className:p.authorTitle,title:e,children:e})}function j({name:e,as:t}){return t?(0,r.jsx)(f.A,{as:t,className:p.authorName,children:e}):(0,r.jsx)("span",{className:p.authorName,children:e})}function b({count:e}){return(0,r.jsx)("span",{className:(0,n.A)(p.authorBlogPostCount),children:e})}function C({as:e,author:t,className:s,count:a}){const{name:i,title:l,url:o,imageURL:c,email:h,page:m}=t,u=m?.permalink||o||h&&`mailto:${h}`||void 0;return(0,r.jsxs)("div",{className:(0,n.A)("avatar margin-bottom--sm",s,p[`author-as-${e}`]),children:[c&&(0,r.jsx)(v,{href:u,className:"avatar__photo-link",children:(0,r.jsx)("img",{className:(0,n.A)("avatar__photo",p.authorImage),src:c,alt:i})}),(i||l)&&(0,r.jsxs)("div",{className:(0,n.A)("avatar__intro",p.authorDetails),children:[(0,r.jsxs)("div",{className:"avatar__name",children:[i&&(0,r.jsx)(v,{href:u,children:(0,r.jsx)(j,{name:i,as:e})}),void 0!==a&&(0,r.jsx)(b,{count:a})]}),!!l&&(0,r.jsx)(w,{title:l}),(0,r.jsx)(x,{author:t})]})]})}},8027:(e,t,s)=>{s.d(t,{A:()=>L});var a=s(6540),n=s(4164),i=s(1656),r=s(4581),l=s(1312),o=s(4096),c=s(6342),h=s(1107),m=s(4848);function u({year:e,yearGroupHeadingClassName:t,children:s}){return(0,m.jsxs)("div",{role:"group",children:[(0,m.jsx)(h.A,{as:"h3",className:t,children:e}),s]})}function d({items:e,yearGroupHeadingClassName:t,ListComponent:s}){if((0,c.p)().blog.sidebar.groupByYear){const a=(0,o.Ki)(e);return(0,m.jsx)(m.Fragment,{children:a.map((([e,a])=>(0,m.jsx)(u,{year:e,yearGroupHeadingClassName:t,children:(0,m.jsx)(s,{items:a})},e)))})}return(0,m.jsx)(s,{items:e})}const g=(0,a.memo)(d),x="sidebar_re4s",f="sidebarItemTitle_pO2u",p="sidebarItemList_Yudw",v="sidebarItem__DBe",w="sidebarItemLink_mo7H",j="sidebarItemLinkActive_I1ZP",b="yearGroupHeading_rMGB",C=({items:e})=>(0,m.jsx)(o.OU,{items:e,ulClassName:(0,n.A)(p,"clean-list"),liClassName:v,linkClassName:w,linkActiveClassName:j});function M({sidebar:e}){const t=(0,o.Gx)(e.items);return(0,m.jsx)("aside",{className:"col col--3",children:(0,m.jsxs)("nav",{className:(0,n.A)(x,"thin-scrollbar"),"aria-label":(0,l.T)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"}),children:[(0,m.jsx)("div",{className:(0,n.A)(f,"margin-bottom--md"),children:e.title}),(0,m.jsx)(g,{items:t,ListComponent:C,yearGroupHeadingClassName:b})]})})}const N=(0,a.memo)(M);var k=s(5600);const A="yearGroupHeading_QT03",_=({items:e})=>(0,m.jsx)(o.OU,{items:e,ulClassName:"menu__list",liClassName:"menu__list-item",linkClassName:"menu__link",linkActiveClassName:"menu__link--active"});function y({sidebar:e}){const t=(0,o.Gx)(e.items);return(0,m.jsx)(g,{items:t,ListComponent:_,yearGroupHeadingClassName:A})}function B(e){return(0,m.jsx)(k.GX,{component:y,props:e})}const I=(0,a.memo)(B);function P({sidebar:e}){const t=(0,r.l)();return e?.items.length?"mobile"===t?(0,m.jsx)(I,{sidebar:e}):(0,m.jsx)(N,{sidebar:e}):null}function L(e){const{sidebar:t,toc:s,children:a,...r}=e,l=t&&t.items.length>0;return(0,m.jsx)(i.A,{...r,children:(0,m.jsx)("div",{className:"container margin-vert--lg",children:(0,m.jsxs)("div",{className:"row",children:[(0,m.jsx)(P,{sidebar:t}),(0,m.jsx)("main",{className:(0,n.A)("col",{"col--7":l,"col--9 col--offset-1":!l}),children:a}),s&&(0,m.jsx)("div",{className:"col col--2",children:s})]})})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/7518.9525ffbe.js b/docs/assets/js/7518.9525ffbe.js new file mode 100644 index 00000000..2702681c --- /dev/null +++ b/docs/assets/js/7518.9525ffbe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7518],{4096:(e,t,s)=>{s.d(t,{in:()=>c,OU:()=>A,Ki:()=>k,kJ:()=>f,x:()=>l,e7:()=>h,J_:()=>p,Gx:()=>N});var a=s(6540),n=s(9532),i=s(6803),r=s(4848);function l(){const e=(0,i.A)(),t=e?.data?.blogMetadata;if(!t)throw new Error("useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context");return t}const o=a.createContext(null);function c({children:e,content:t,isBlogPostPage:s=!1}){const n=function({content:e,isBlogPostPage:t}){return(0,a.useMemo)(()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,toc:e.toc,isBlogPostPage:t}),[e,t])}({content:t,isBlogPostPage:s});return(0,r.jsx)(o.Provider,{value:n,children:e})}function h(){const e=(0,a.useContext)(o);if(null===e)throw new n.dV("BlogPostProvider");return e}var m=s(6025),u=s(4586);const d=e=>new Date(e).toISOString();function g(e){const t=e.map(v);return{author:1===t.length?t[0]:t}}function x(e,t,s){return e?{image:w({imageUrl:t(e,{absolute:!0}),caption:`title image for the blog post: ${s}`})}:{}}function f(e){const{siteConfig:t}=(0,u.A)(),{withBaseUrl:s}=(0,m.hH)(),{metadata:{blogDescription:a,blogTitle:n,permalink:i}}=e,r=`${t.url}${i}`;return{"@context":"https://schema.org","@type":"Blog","@id":r,mainEntityOfPage:r,headline:n,description:a,blogPost:e.items.map(e=>function(e,t,s){const{assets:a,frontMatter:n,metadata:i}=e,{date:r,title:l,description:o,lastUpdatedAt:c}=i,h=a.image??n.image,m=n.keywords??[],u=`${t.url}${i.permalink}`,f=c?d(c):void 0;return{"@type":"BlogPosting","@id":u,mainEntityOfPage:u,url:u,headline:l,name:l,description:o,datePublished:r,...f?{dateModified:f}:{},...g(i.authors),...x(h,s,l),...m?{keywords:m}:{}}}(e.content,t,s))}}function p(){const e=l(),{assets:t,metadata:s}=h(),{siteConfig:a}=(0,u.A)(),{withBaseUrl:n}=(0,m.hH)(),{date:i,title:r,description:o,frontMatter:c,lastUpdatedAt:f}=s,p=t.image??c.image,v=c.keywords??[],w=f?d(f):void 0,j=`${a.url}${s.permalink}`;return{"@context":"https://schema.org","@type":"BlogPosting","@id":j,mainEntityOfPage:j,url:j,headline:r,name:r,description:o,datePublished:i,...w?{dateModified:w}:{},...g(s.authors),...x(p,n,r),...v?{keywords:v}:{},isPartOf:{"@type":"Blog","@id":`${a.url}${e.blogBasePath}`,name:e.blogTitle}}}function v(e){return{"@type":"Person",...e.name?{name:e.name}:{},...e.title?{description:e.title}:{},...e.url?{url:e.url}:{},...e.email?{email:e.email}:{},...e.imageURL?{image:e.imageURL}:{}}}function w({imageUrl:e,caption:t}){return{"@type":"ImageObject","@id":e,url:e,contentUrl:e,caption:t}}var j=s(6347),b=s(8774),C=s(1682),M=s(9169);function N(e){const{pathname:t}=(0,j.zy)();return(0,a.useMemo)(()=>e.filter(e=>function(e,t){return!(e.unlisted&&!(0,M.ys)(e.permalink,t))}(e,t)),[e,t])}function k(e){const t=(0,C.$z)(e,e=>`${new Date(e.date).getFullYear()}`),s=Object.entries(t);return s.reverse(),s}function A({items:e,ulClassName:t,liClassName:s,linkClassName:a,linkActiveClassName:n}){return(0,r.jsx)("ul",{className:t,children:e.map(e=>(0,r.jsx)("li",{className:s,children:(0,r.jsx)(b.A,{isNavLink:!0,to:e.permalink,className:a,activeClassName:n,children:e.title})},e.permalink))})}},5846:(e,t,s)=>{s.d(t,{W:()=>c});var a=s(6540),n=s(4586);const i=["zero","one","two","few","many","other"];function r(e){return i.filter(t=>e.includes(t))}const l={locale:"en",pluralForms:r(["one","other"]),select:e=>1===e?"one":"other"};function o(){const{i18n:{currentLocale:e}}=(0,n.A)();return(0,a.useMemo)(()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:r(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),l}},[e])}function c(){const e=o();return{selectMessage:(t,s)=>function(e,t,s){const a=e.split("|");if(1===a.length)return a[0];a.length>s.pluralForms.length&&console.error(`For locale=${s.locale}, a maximum of ${s.pluralForms.length} plural forms are expected (${s.pluralForms.join(",")}), but the message contains ${a.length}: ${e}`);const n=s.select(t),i=s.pluralForms.indexOf(n);return a[Math.min(i,a.length-1)]}(s,t,e)}}},6382:(e,t,s)=>{s.d(t,{A:()=>C});var a=s(6540),n=s(4164),i=s(8774),r=s(4848);const l="githubSvg_Uu4N";const o="xSvg_y3PF";const c=function(e){return(0,r.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...e,children:[(0,r.jsx)("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),(0,r.jsx)("path",{d:"M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0"}),(0,r.jsx)("path",{d:"M3.6 9h16.8"}),(0,r.jsx)("path",{d:"M3.6 15h16.8"}),(0,r.jsx)("path",{d:"M11.5 3a17 17 0 0 0 0 18"}),(0,r.jsx)("path",{d:"M12.5 3a17 17 0 0 1 0 18"})]})};const h="instagramSvg_YC40";const m="threadsSvg_PTXY";const u={authorSocials:"authorSocials_rSDt",authorSocialLink:"authorSocialLink_owbf",authorSocialIcon:"authorSocialIcon_XYv3"},d={twitter:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 209",width:"1em",height:"1em",preserveAspectRatio:"xMidYMid",...e,children:(0,r.jsx)("path",{d:"M256 25.45c-9.42 4.177-19.542 7-30.166 8.27 10.845-6.5 19.172-16.793 23.093-29.057a105.183 105.183 0 0 1-33.351 12.745C205.995 7.201 192.346.822 177.239.822c-29.006 0-52.523 23.516-52.523 52.52 0 4.117.465 8.125 1.36 11.97-43.65-2.191-82.35-23.1-108.255-54.876-4.52 7.757-7.11 16.78-7.11 26.404 0 18.222 9.273 34.297 23.365 43.716a52.312 52.312 0 0 1-23.79-6.57c-.003.22-.003.44-.003.661 0 25.447 18.104 46.675 42.13 51.5a52.592 52.592 0 0 1-23.718.9c6.683 20.866 26.08 36.05 49.062 36.475-17.975 14.086-40.622 22.483-65.228 22.483-4.24 0-8.42-.249-12.529-.734 23.243 14.902 50.85 23.597 80.51 23.597 96.607 0 149.434-80.031 149.434-149.435 0-2.278-.05-4.543-.152-6.795A106.748 106.748 0 0 0 256 25.45",fill:"#55acee"})})},label:"Twitter"},github:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 256 250",preserveAspectRatio:"xMidYMid",style:{"--dark":"#000","--light":"#fff"},...e,className:(0,n.A)(e.className,l),children:(0,r.jsx)("path",{d:"M128.001 0C57.317 0 0 57.307 0 128.001c0 56.554 36.676 104.535 87.535 121.46 6.397 1.185 8.746-2.777 8.746-6.158 0-3.052-.12-13.135-.174-23.83-35.61 7.742-43.124-15.103-43.124-15.103-5.823-14.795-14.213-18.73-14.213-18.73-11.613-7.944.876-7.78.876-7.78 12.853.902 19.621 13.19 19.621 13.19 11.417 19.568 29.945 13.911 37.249 10.64 1.149-8.272 4.466-13.92 8.127-17.116-28.431-3.236-58.318-14.212-58.318-63.258 0-13.975 5-25.394 13.188-34.358-1.329-3.224-5.71-16.242 1.24-33.874 0 0 10.749-3.44 35.21 13.121 10.21-2.836 21.16-4.258 32.038-4.307 10.878.049 21.837 1.47 32.066 4.307 24.431-16.56 35.165-13.12 35.165-13.12 6.967 17.63 2.584 30.65 1.255 33.873 8.207 8.964 13.173 20.383 13.173 34.358 0 49.163-29.944 59.988-58.447 63.157 4.591 3.972 8.682 11.762 8.682 23.704 0 17.126-.148 30.91-.148 35.126 0 3.407 2.304 7.398 8.792 6.14C219.37 232.5 256 184.537 256 128.002 256 57.307 198.691 0 128.001 0Zm-80.06 182.34c-.282.636-1.283.827-2.194.39-.929-.417-1.45-1.284-1.15-1.922.276-.655 1.279-.838 2.205-.399.93.418 1.46 1.293 1.139 1.931Zm6.296 5.618c-.61.566-1.804.303-2.614-.591-.837-.892-.994-2.086-.375-2.66.63-.566 1.787-.301 2.626.591.838.903 1 2.088.363 2.66Zm4.32 7.188c-.785.545-2.067.034-2.86-1.104-.784-1.138-.784-2.503.017-3.05.795-.547 2.058-.055 2.861 1.075.782 1.157.782 2.522-.019 3.08Zm7.304 8.325c-.701.774-2.196.566-3.29-.49-1.119-1.032-1.43-2.496-.726-3.27.71-.776 2.213-.558 3.315.49 1.11 1.03 1.45 2.505.701 3.27Zm9.442 2.81c-.31 1.003-1.75 1.459-3.199 1.033-1.448-.439-2.395-1.613-2.103-2.626.301-1.01 1.747-1.484 3.207-1.028 1.446.436 2.396 1.602 2.095 2.622Zm10.744 1.193c.036 1.055-1.193 1.93-2.715 1.95-1.53.034-2.769-.82-2.786-1.86 0-1.065 1.202-1.932 2.733-1.958 1.522-.03 2.768.818 2.768 1.868Zm10.555-.405c.182 1.03-.875 2.088-2.387 2.37-1.485.271-2.861-.365-3.05-1.386-.184-1.056.893-2.114 2.376-2.387 1.514-.263 2.868.356 3.061 1.403Z"})})},label:"GitHub"},stackoverflow:{Icon:function(e){return(0,r.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 169.61 200",width:"1em",height:"1em",...e,children:[(0,r.jsx)("path",{d:"M140.44 178.38v-48.65h21.61V200H0v-70.27h21.61v48.65z",fill:"#bcbbbb"}),(0,r.jsx)("path",{d:"M124.24 140.54l4.32-16.22-86.97-17.83-3.78 17.83zM49.7 82.16L130.72 120l7.56-16.22-81.02-37.83zm22.68-40l68.06 57.3 11.35-13.51-68.6-57.3-11.35 13.51zM116.14 0l-14.59 10.81 53.48 71.89 14.58-10.81zM37.81 162.16h86.43v-16.21H37.81z",fill:"#f48024"})]})},label:"Stack Overflow"},linkedin:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",preserveAspectRatio:"xMidYMid",viewBox:"0 0 256 256",...e,children:(0,r.jsx)("path",{d:"M218.123 218.127h-37.931v-59.403c0-14.165-.253-32.4-19.728-32.4-19.756 0-22.779 15.434-22.779 31.369v60.43h-37.93V95.967h36.413v16.694h.51a39.907 39.907 0 0 1 35.928-19.733c38.445 0 45.533 25.288 45.533 58.186l-.016 67.013ZM56.955 79.27c-12.157.002-22.014-9.852-22.016-22.009-.002-12.157 9.851-22.014 22.008-22.016 12.157-.003 22.014 9.851 22.016 22.008A22.013 22.013 0 0 1 56.955 79.27m18.966 138.858H37.95V95.967h37.97v122.16ZM237.033.018H18.89C8.58-.098.125 8.161-.001 18.471v219.053c.122 10.315 8.576 18.582 18.89 18.474h218.144c10.336.128 18.823-8.139 18.966-18.474V18.454c-.147-10.33-8.635-18.588-18.966-18.453",fill:"#0A66C2"})})},label:"LinkedIn"},x:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",fill:"none",viewBox:"0 0 1200 1227",style:{"--dark":"#000","--light":"#fff"},...e,className:(0,n.A)(e.className,o),children:(0,r.jsx)("path",{d:"M714.163 519.284 1160.89 0h-105.86L667.137 450.887 357.328 0H0l468.492 681.821L0 1226.37h105.866l409.625-476.152 327.181 476.152H1200L714.137 519.284h.026ZM569.165 687.828l-47.468-67.894-377.686-540.24h162.604l304.797 435.991 47.468 67.894 396.2 566.721H892.476L569.165 687.854v-.026Z"})})},label:"X"},bluesky:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",preserveAspectRatio:"xMidYMid",viewBox:"0 0 256 226",...e,children:(0,r.jsx)("path",{fill:"#1185FE",d:"M55.491 15.172c29.35 22.035 60.917 66.712 72.509 90.686 11.592-23.974 43.159-68.651 72.509-90.686C221.686-.727 256-13.028 256 26.116c0 7.818-4.482 65.674-7.111 75.068-9.138 32.654-42.436 40.983-72.057 35.942 51.775 8.812 64.946 38 36.501 67.187-54.021 55.433-77.644-13.908-83.696-31.676-1.11-3.257-1.63-4.78-1.637-3.485-.008-1.296-.527.228-1.637 3.485-6.052 17.768-29.675 87.11-83.696 31.676-28.445-29.187-15.274-58.375 36.5-67.187-29.62 5.041-62.918-3.288-72.056-35.942C4.482 91.79 0 33.934 0 26.116 0-13.028 34.314-.727 55.491 15.172Z"})})},label:"Bluesky"},instagram:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",preserveAspectRatio:"xMidYMid",viewBox:"0 0 256 256",style:{"--dark":"#000","--light":"#fff"},...e,className:(0,n.A)(e.className,h),children:(0,r.jsx)("path",{d:"M128 23.064c34.177 0 38.225.13 51.722.745 12.48.57 19.258 2.655 23.769 4.408 5.974 2.322 10.238 5.096 14.717 9.575 4.48 4.479 7.253 8.743 9.575 14.717 1.753 4.511 3.838 11.289 4.408 23.768.615 13.498.745 17.546.745 51.723 0 34.178-.13 38.226-.745 51.723-.57 12.48-2.655 19.257-4.408 23.768-2.322 5.974-5.096 10.239-9.575 14.718-4.479 4.479-8.743 7.253-14.717 9.574-4.511 1.753-11.289 3.839-23.769 4.408-13.495.616-17.543.746-51.722.746-34.18 0-38.228-.13-51.723-.746-12.48-.57-19.257-2.655-23.768-4.408-5.974-2.321-10.239-5.095-14.718-9.574-4.479-4.48-7.253-8.744-9.574-14.718-1.753-4.51-3.839-11.288-4.408-23.768-.616-13.497-.746-17.545-.746-51.723 0-34.177.13-38.225.746-51.722.57-12.48 2.655-19.258 4.408-23.769 2.321-5.974 5.095-10.238 9.574-14.717 4.48-4.48 8.744-7.253 14.718-9.575 4.51-1.753 11.288-3.838 23.768-4.408 13.497-.615 17.545-.745 51.723-.745M128 0C93.237 0 88.878.147 75.226.77c-13.625.622-22.93 2.786-31.071 5.95-8.418 3.271-15.556 7.648-22.672 14.764C14.367 28.6 9.991 35.738 6.72 44.155 3.555 52.297 1.392 61.602.77 75.226.147 88.878 0 93.237 0 128c0 34.763.147 39.122.77 52.774.622 13.625 2.785 22.93 5.95 31.071 3.27 8.417 7.647 15.556 14.763 22.672 7.116 7.116 14.254 11.492 22.672 14.763 8.142 3.165 17.446 5.328 31.07 5.95 13.653.623 18.012.77 52.775.77s39.122-.147 52.774-.77c13.624-.622 22.929-2.785 31.07-5.95 8.418-3.27 15.556-7.647 22.672-14.763 7.116-7.116 11.493-14.254 14.764-22.672 3.164-8.142 5.328-17.446 5.95-31.07.623-13.653.77-18.012.77-52.775s-.147-39.122-.77-52.774c-.622-13.624-2.786-22.929-5.95-31.07-3.271-8.418-7.648-15.556-14.764-22.672C227.4 14.368 220.262 9.99 211.845 6.72c-8.142-3.164-17.447-5.328-31.071-5.95C167.122.147 162.763 0 128 0Zm0 62.27C91.698 62.27 62.27 91.7 62.27 128c0 36.302 29.428 65.73 65.73 65.73 36.301 0 65.73-29.428 65.73-65.73 0-36.301-29.429-65.73-65.73-65.73Zm0 108.397c-23.564 0-42.667-19.103-42.667-42.667S104.436 85.333 128 85.333s42.667 19.103 42.667 42.667-19.103 42.667-42.667 42.667Zm83.686-110.994c0 8.484-6.876 15.36-15.36 15.36-8.483 0-15.36-6.876-15.36-15.36 0-8.483 6.877-15.36 15.36-15.36 8.484 0 15.36 6.877 15.36 15.36Z"})})},label:"Instagram"},threads:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg","aria-label":"Threads",viewBox:"0 0 192 192",width:"1em",fill:"none",height:"1em",style:{"--dark":"#000","--light":"#fff"},...e,className:(0,n.A)(e.className,m),children:(0,r.jsx)("path",{d:"M141.537 88.988a66.667 66.667 0 0 0-2.518-1.143c-1.482-27.307-16.403-42.94-41.457-43.1h-.34c-14.986 0-27.449 6.396-35.12 18.036l13.779 9.452c5.73-8.695 14.724-10.548 21.348-10.548h.229c8.249.053 14.474 2.452 18.503 7.129 2.932 3.405 4.893 8.111 5.864 14.05-7.314-1.243-15.224-1.626-23.68-1.14-23.82 1.371-39.134 15.264-38.105 34.568.522 9.792 5.4 18.216 13.735 23.719 7.047 4.652 16.124 6.927 25.557 6.412 12.458-.683 22.231-5.436 29.049-14.127 5.178-6.6 8.453-15.153 9.899-25.93 5.937 3.583 10.337 8.298 12.767 13.966 4.132 9.635 4.373 25.468-8.546 38.376-11.319 11.308-24.925 16.2-45.488 16.351-22.809-.169-40.06-7.484-51.275-21.742C35.236 139.966 29.808 120.682 29.605 96c.203-24.682 5.63-43.966 16.133-57.317C56.954 24.425 74.204 17.11 97.013 16.94c22.975.17 40.526 7.52 52.171 21.847 5.71 7.026 10.015 15.86 12.853 26.162l16.147-4.308c-3.44-12.68-8.853-23.606-16.219-32.668C147.036 9.607 125.202.195 97.07 0h-.113C68.882.194 47.292 9.642 32.788 28.08 19.882 44.485 13.224 67.315 13.001 95.932L13 96v.067c.224 28.617 6.882 51.447 19.788 67.854C47.292 182.358 68.882 191.806 96.957 192h.113c24.96-.173 42.554-6.708 57.048-21.189 18.963-18.945 18.392-42.692 12.142-57.27-4.484-10.454-13.033-18.945-24.723-24.553ZM98.44 129.507c-10.44.588-21.286-4.098-21.82-14.135-.397-7.442 5.296-15.746 22.461-16.735 1.966-.114 3.895-.169 5.79-.169 6.235 0 12.068.606 17.371 1.765-1.978 24.702-13.58 28.713-23.802 29.274Z"})})},label:"Threads"},mastodon:{Icon:function(e){const t=(0,a.useId)();return(0,r.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 61 65",width:"1em",height:"1em",...e,children:[(0,r.jsx)("path",{fill:`url(#${t})`,d:"M60.754 14.39C59.814 7.406 53.727 1.903 46.512.836 45.294.656 40.682 0 29.997 0h-.08C19.23 0 16.938.656 15.72.836 8.705 1.873 2.299 6.82.745 13.886c-.748 3.48-.828 7.338-.689 10.877.198 5.075.237 10.142.697 15.197a71.482 71.482 0 0 0 1.664 9.968c1.477 6.056 7.458 11.096 13.317 13.152a35.718 35.718 0 0 0 19.484 1.028 28.365 28.365 0 0 0 2.107-.576c1.572-.5 3.413-1.057 4.766-2.038a.154.154 0 0 0 .062-.118v-4.899a.146.146 0 0 0-.055-.111.145.145 0 0 0-.122-.028 54 54 0 0 1-12.644 1.478c-7.328 0-9.298-3.478-9.863-4.925a15.258 15.258 0 0 1-.857-3.882.142.142 0 0 1 .178-.145 52.976 52.976 0 0 0 12.437 1.477c1.007 0 2.012 0 3.02-.026 4.213-.119 8.654-.334 12.8-1.144.103-.02.206-.038.295-.065 6.539-1.255 12.762-5.196 13.394-15.176.024-.393.083-4.115.083-4.523.003-1.386.446-9.829-.065-15.017Z"}),(0,r.jsx)("path",{fill:"#fff",d:"M50.394 22.237v17.35H43.52V22.749c0-3.545-1.478-5.353-4.483-5.353-3.303 0-4.958 2.139-4.958 6.364v9.217h-6.835V23.76c0-4.225-1.657-6.364-4.96-6.364-2.988 0-4.48 1.808-4.48 5.353v16.84H10.93V22.237c0-3.545.905-6.362 2.715-8.45 1.868-2.082 4.317-3.152 7.358-3.152 3.519 0 6.178 1.354 7.951 4.057l1.711 2.871 1.714-2.871c1.773-2.704 4.432-4.056 7.945-4.056 3.038 0 5.487 1.069 7.36 3.152 1.81 2.085 2.712 4.902 2.71 8.449Z"}),(0,r.jsx)("defs",{children:(0,r.jsxs)("linearGradient",{id:t,x1:30.5,x2:30.5,y1:0,y2:65,gradientUnits:"userSpaceOnUse",children:[(0,r.jsx)("stop",{stopColor:"#6364FF"}),(0,r.jsx)("stop",{offset:1,stopColor:"#563ACC"})]})})]})},label:"Mastodon"},youtube:{Icon:function(e){return(0,r.jsxs)("svg",{viewBox:"0 0 256 180",width:"1em",height:"1em",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid",...e,children:[(0,r.jsx)("path",{d:"M250.346 28.075A32.18 32.18 0 0 0 227.69 5.418C207.824 0 127.87 0 127.87 0S47.912.164 28.046 5.582A32.18 32.18 0 0 0 5.39 28.24c-6.009 35.298-8.34 89.084.165 122.97a32.18 32.18 0 0 0 22.656 22.657c19.866 5.418 99.822 5.418 99.822 5.418s79.955 0 99.82-5.418a32.18 32.18 0 0 0 22.657-22.657c6.338-35.348 8.291-89.1-.164-123.134Z",fill:"red"}),(0,r.jsx)("path",{fill:"#FFF",d:"m102.421 128.06 66.328-38.418-66.328-38.418z"})]})},label:"YouTube"},twitch:{Icon:function(e){return(0,r.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",x:0,y:0,viewBox:"0 0 2400 2800",width:"1em",height:"1em",...e,children:[(0,r.jsx)("path",{d:"m2200 1300-400 400h-400l-350 350v-350H600V200h1600z",fill:"#fff"}),(0,r.jsxs)("g",{children:[(0,r.jsx)("path",{d:"M500 0 0 500v1800h600v500l500-500h400l900-900V0H500zm1700 1300-400 400h-400l-350 350v-350H600V200h1600v1100z",fill:"#9146ff"}),(0,r.jsx)("path",{d:"M1700 550h200v600h-200zM1150 550h200v600h-200z",fill:"#9146ff"})]})]})},label:"Twitch"}};function g({platform:e,link:t}){const{Icon:s,label:a}=d[l=e]??{Icon:c,label:l};var l;return(0,r.jsx)(i.A,{className:u.authorSocialLink,href:t,title:a,children:(0,r.jsx)(s,{className:(0,n.A)(u.authorSocialLink)})})}function x({author:e}){const t=Object.entries(e.socials??{});return(0,r.jsx)("div",{className:u.authorSocials,children:t.map(([e,t])=>(0,r.jsx)(g,{platform:e,link:t},e))})}var f=s(1107);const p={authorImage:"authorImage_XqGP","author-as-h1":"author-as-h1_n9oJ","author-as-h2":"author-as-h2_gXvM",authorDetails:"authorDetails_lV9A",authorName:"authorName_yefp",authorTitle:"authorTitle_nd0D",authorBlogPostCount:"authorBlogPostCount_iiJ5"};function v(e){return e.href?(0,r.jsx)(i.A,{...e}):(0,r.jsx)(r.Fragment,{children:e.children})}function w({title:e}){return(0,r.jsx)("small",{className:p.authorTitle,title:e,children:e})}function j({name:e,as:t}){return t?(0,r.jsx)(f.A,{as:t,className:p.authorName,children:e}):(0,r.jsx)("span",{className:p.authorName,children:e})}function b({count:e}){return(0,r.jsx)("span",{className:(0,n.A)(p.authorBlogPostCount),children:e})}function C({as:e,author:t,className:s,count:a}){const{name:i,title:l,url:o,imageURL:c,email:h,page:m}=t,u=m?.permalink||o||h&&`mailto:${h}`||void 0;return(0,r.jsxs)("div",{className:(0,n.A)("avatar margin-bottom--sm",s,p[`author-as-${e}`]),children:[c&&(0,r.jsx)(v,{href:u,className:"avatar__photo-link",children:(0,r.jsx)("img",{className:(0,n.A)("avatar__photo",p.authorImage),src:c,alt:i})}),(i||l)&&(0,r.jsxs)("div",{className:(0,n.A)("avatar__intro",p.authorDetails),children:[(0,r.jsxs)("div",{className:"avatar__name",children:[i&&(0,r.jsx)(v,{href:u,children:(0,r.jsx)(j,{name:i,as:e})}),void 0!==a&&(0,r.jsx)(b,{count:a})]}),!!l&&(0,r.jsx)(w,{title:l}),(0,r.jsx)(x,{author:t})]})]})}},8027:(e,t,s)=>{s.d(t,{A:()=>L});var a=s(6540),n=s(4164),i=s(1656),r=s(4581),l=s(1312),o=s(4096),c=s(6342),h=s(1107),m=s(4848);function u({year:e,yearGroupHeadingClassName:t,children:s}){return(0,m.jsxs)("div",{role:"group",children:[(0,m.jsx)(h.A,{as:"h3",className:t,children:e}),s]})}function d({items:e,yearGroupHeadingClassName:t,ListComponent:s}){if((0,c.p)().blog.sidebar.groupByYear){const a=(0,o.Ki)(e);return(0,m.jsx)(m.Fragment,{children:a.map(([e,a])=>(0,m.jsx)(u,{year:e,yearGroupHeadingClassName:t,children:(0,m.jsx)(s,{items:a})},e))})}return(0,m.jsx)(s,{items:e})}const g=(0,a.memo)(d),x="sidebar_re4s",f="sidebarItemTitle_pO2u",p="sidebarItemList_Yudw",v="sidebarItem__DBe",w="sidebarItemLink_mo7H",j="sidebarItemLinkActive_I1ZP",b="yearGroupHeading_rMGB",C=({items:e})=>(0,m.jsx)(o.OU,{items:e,ulClassName:(0,n.A)(p,"clean-list"),liClassName:v,linkClassName:w,linkActiveClassName:j});function M({sidebar:e}){const t=(0,o.Gx)(e.items);return(0,m.jsx)("aside",{className:"col col--3",children:(0,m.jsxs)("nav",{className:(0,n.A)(x,"thin-scrollbar"),"aria-label":(0,l.T)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"}),children:[(0,m.jsx)("div",{className:(0,n.A)(f,"margin-bottom--md"),children:e.title}),(0,m.jsx)(g,{items:t,ListComponent:C,yearGroupHeadingClassName:b})]})})}const N=(0,a.memo)(M);var k=s(5600);const A="yearGroupHeading_QT03",_=({items:e})=>(0,m.jsx)(o.OU,{items:e,ulClassName:"menu__list",liClassName:"menu__list-item",linkClassName:"menu__link",linkActiveClassName:"menu__link--active"});function y({sidebar:e}){const t=(0,o.Gx)(e.items);return(0,m.jsx)(g,{items:t,ListComponent:_,yearGroupHeadingClassName:A})}function B(e){return(0,m.jsx)(k.GX,{component:y,props:e})}const I=(0,a.memo)(B);function P({sidebar:e}){const t=(0,r.l)();return e?.items.length?"mobile"===t?(0,m.jsx)(I,{sidebar:e}):(0,m.jsx)(N,{sidebar:e}):null}function L(e){const{sidebar:t,toc:s,children:a,...r}=e,l=t&&t.items.length>0;return(0,m.jsx)(i.A,{...r,children:(0,m.jsx)("div",{className:"container margin-vert--lg",children:(0,m.jsxs)("div",{className:"row",children:[(0,m.jsx)(P,{sidebar:t}),(0,m.jsx)("main",{className:(0,n.A)("col",{"col--7":l,"col--9 col--offset-1":!l}),children:a}),s&&(0,m.jsx)("div",{className:"col col--2",children:s})]})})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/79ae4ea7.1416ba4f.js b/docs/assets/js/79ae4ea7.1416ba4f.js new file mode 100644 index 00000000..8a4eb857 --- /dev/null +++ b/docs/assets/js/79ae4ea7.1416ba4f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4340],{2173:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/llm-plat-9ac69c0ffd8c387d177e582611b8c775.png"},4311:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"permalink":"/BharatMLStack/blog/post-three","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-four/index.md","source":"@site/blog/bharatmlstack-history/post-four/index.md","title":"Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving","description":"BharatMLStack","date":"2025-03-29T00:00:00.000Z","tags":[{"inline":true,"label":"llm","permalink":"/BharatMLStack/blog/tags/llm"},{"inline":true,"label":"vllm","permalink":"/BharatMLStack/blog/tags/vllm"},{"inline":true,"label":"tensorrt-llm","permalink":"/BharatMLStack/blog/tags/tensorrt-llm"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"},{"inline":true,"label":"bharatmlstack","permalink":"/BharatMLStack/blog/tags/bharatmlstack"}],"readingTime":13.38,"hasTruncateMarker":false,"authors":[{"name":"Jaya Kumar","title":"Lead ML Engineer @ Meesho","url":"https://github.com/jayakommuru","imageURL":"https://github.com/jayakommuru.png","key":"jaya","page":null}],"frontMatter":{"slug":"post-three","title":"Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving","authors":["jaya"],"date":"2025-3-29","tags":["llm","vllm","tensorrt-llm","mlplatform","meesho","bharatmlstack"]},"unlisted":false,"prevItem":{"title":"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale","permalink":"/BharatMLStack/blog/post-five"},"nextItem":{"title":"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search","permalink":"/BharatMLStack/blog/post-three"}}');var r=i(4848),s=i(8453);const a={slug:"post-three",title:"Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving",authors:["jaya"],date:"2025-3-29",tags:["llm","vllm","tensorrt-llm","mlplatform","meesho","bharatmlstack"]},o=void 0,l={authorsImageUrls:[void 0]},c=[{value:"Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving",id:"designing-a-production-grade-llm-inference-platform-from-model-weights-to-scalable-gpu-serving",level:2},{value:"Why LLM Inference Is not just bigger ML model serving",id:"why-llm-inference-is-not-just-bigger-ml-model-serving",level:2},{value:"Autoregressive Generation and Sequential Computation:",id:"autoregressive-generation-and-sequential-computation",level:3},{value:"Prefill and Decode Phases:",id:"prefill-and-decode-phases",level:3},{value:"Context Management and KV Caching:",id:"context-management-and-kv-caching",level:3},{value:"Dynamic and Irregular Workloads:",id:"dynamic-and-irregular-workloads",level:3},{value:"Streaming and User Experience Constraints:",id:"streaming-and-user-experience-constraints",level:3},{value:"LLMOps: High-Level Architecture",id:"llmops-high-level-architecture",level:2},{value:"Supported Inference backends (TensorRT LLM, Dynamo & vLLM)",id:"supported-inference-backends-tensorrt-llm--dynamo--vllm",level:2},{value:"Conclusion",id:"conclusion",level:2},{value:"Future Explorations",id:"future-explorations",level:2}];function d(e){const n={h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"BharatMLStack",src:i(7996).A+"",width:"1396",height:"460"})}),"\n",(0,r.jsx)(n.h2,{id:"designing-a-production-grade-llm-inference-platform-from-model-weights-to-scalable-gpu-serving",children:"Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving"}),"\n",(0,r.jsx)(n.p,{children:"Serving large language models in production introduces new challenges across infrastructure, performance optimization, and operational lifecycle management. The LLM Inference Platform addresses these challenges by providing a unified system for deploying and managing open-source and fine-tuned LLMs at scale."}),"\n",(0,r.jsx)(n.p,{children:"The platform implements a complete LLMOps lifecycle \u2014 from model registration and automated compilation to deployment, runtime optimization, and monitoring. Designed as a self-service environment, users can onboard models directly from open repositories such as Hugging Face or upload custom fine-tuned models, and deploy them using a single-click workflow with no manual infrastructure or configuration steps required."}),"\n",(0,r.jsx)(n.p,{children:"In addition to fully automated deployment, the platform allows users to select and apply custom inference optimization techniques \u2014 such as quantization strategies, batching configurations, and runtime-specific performance enhancements \u2014 enabling teams to balance latency, throughput, and cost based on their use case. The goal is to reduce operational friction while enabling high-performance, production-grade LLM inference."}),"\n",(0,r.jsx)(n.h2,{id:"why-llm-inference-is-not-just-bigger-ml-model-serving",children:"Why LLM Inference Is not just bigger ML model serving"}),"\n",(0,r.jsx)(n.p,{children:"Large language model (LLM) inference introduces a fundamentally different set of challenges compared to traditional machine learning inference. While classical ML models typically perform a single forward pass to produce a fixed prediction, LLMs operate as autoregressive systems, generating outputs token by token based on previously generated context. This difference dramatically changes how inference systems must be designed, optimized, and scaled."}),"\n",(0,r.jsx)(n.h3,{id:"autoregressive-generation-and-sequential-computation",children:"Autoregressive Generation and Sequential Computation:"}),"\n",(0,r.jsx)(n.p,{children:"Unlike traditional models such as classifiers or recommenders \u2014 where inference cost is relatively constant \u2014 LLMs generate responses incrementally. Each new token depends on all previously generated tokens, making inference inherently sequential and dynamic. This means latency and compute requirements vary significantly depending on prompt length and output size, introducing complexity in scheduling and resource allocation.\nBecause tokens cannot be generated fully in parallel during decoding, GPUs may become underutilized without specialized batching and scheduling strategies. This has led to the development of dedicated LLM inference engines optimized for token-level execution."}),"\n",(0,r.jsx)(n.h3,{id:"prefill-and-decode-phases",children:"Prefill and Decode Phases:"}),"\n",(0,r.jsx)(n.p,{children:"LLM inference typically consists of two distinct stages:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Prefill phase \u2014 the model processes the input prompt and builds internal representations. This stage is compute-heavy and highly parallelizable."}),"\n",(0,r.jsx)(n.li,{children:"Decode phase \u2014 the model generates tokens sequentially, predicting one token at a time using previously generated context."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The decode stage often becomes memory-bound rather than compute-bound, which creates new performance bottlenecks compared to traditional ML workloads."}),"\n",(0,r.jsx)(n.h3,{id:"context-management-and-kv-caching",children:"Context Management and KV Caching:"}),"\n",(0,r.jsx)(n.p,{children:"Another fundamental difference lies in how LLMs maintain context. Transformer-based models rely on attention mechanisms that require access to past token representations. To avoid recomputing these representations repeatedly, inference engines use key-value (KV) caching, which stores intermediate activations from previous tokens.\nKV caching significantly improves performance by eliminating redundant computation, but it introduces new challenges:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Memory consumption grows with sequence length and batch size"}),"\n",(0,r.jsx)(n.li,{children:"GPU memory becomes a critical bottleneck"}),"\n",(0,r.jsx)(n.li,{children:"Efficient memory management becomes essential for scaling concurrent requests"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"This tradeoff between compute efficiency and memory usage is unique to LLM inference workloads."}),"\n",(0,r.jsx)(n.h3,{id:"dynamic-and-irregular-workloads",children:"Dynamic and Irregular Workloads:"}),"\n",(0,r.jsx)(n.p,{children:"Traditional ML inference typically operates on fixed-size inputs with predictable latency. In contrast, LLM requests vary widely in prompt length, output length, and runtime behavior. As a result:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Batch sizes must be dynamic rather than static"}),"\n",(0,r.jsx)(n.li,{children:"Requests may enter and leave batches asynchronously"}),"\n",(0,r.jsx)(n.li,{children:"Scheduling systems must continuously rebalance workloads to maximize GPU utilization"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"These characteristics require specialized serving architectures that differ significantly from standard ML serving pipelines."}),"\n",(0,r.jsx)(n.h3,{id:"streaming-and-user-experience-constraints",children:"Streaming and User Experience Constraints:"}),"\n",(0,r.jsx)(n.p,{children:"Another distinguishing factor is the expectation of real-time streaming responses. Instead of returning a single output, LLM systems often stream tokens to users as they are generated.\nBecause of these differences \u2014 sequential generation, growing memory requirements, dynamic workloads, and streaming constraints \u2014 LLM inference cannot be treated as a simple extension of existing ML serving systems. Production platforms must incorporate specialized runtime engines, advanced optimization techniques, and observability tailored specifically to LLM workloads."}),"\n",(0,r.jsx)(n.h2,{id:"llmops-high-level-architecture",children:"LLMOps: High-Level Architecture"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"LLM Architecture",src:i(2173).A+"",width:"1302",height:"830"})}),"\n",(0,r.jsx)(n.p,{children:"The LLM Inference Framework is designed as a fully automated, end-to-end system for deploying and operating open-source and fine-tuned large language models at scale. The architecture abstracts the complexity of model optimization, hardware selection, deployment, and runtime management into a unified workflow that enables users to move from raw model weights to production-ready inference endpoints with minimal manual intervention."}),"\n",(0,r.jsx)(n.p,{children:"Our LLM Inference Framework is architected not just as a serving engine, but as a complete lifecycle management system. As illustrated in the high-level design below, the platform automates the journey of a model through seven distinct stages, ensuring reproducibility, performance, and scalability."}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Onboarding & Registration (The Source of Truth)"}),"\n",(0,r.jsx)(n.p,{children:"The lifecycle begins with the Data Scientist or engineer."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Model Ingestion: Users onboard models\u2014whether open-source (Hugging Face, NeMo) or internally fine-tuned\u2014via the Truffle Box SDK/UI."}),"\n",(0,r.jsx)(n.li,{children:'LLM + Prompt Registry: Unlike traditional systems that only track model weights, our registry is a unified control plane. It stores both the Model Artifacts and the Prompt Templates. This allows Data Scientists to register and version-control prompts (e.g., "customer_support_v2") independently of the application code.'}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:'The "Black Box" Build Engine'}),"\n",(0,r.jsx)(n.p,{children:"Once a model is registered, the Automated LLM Compiler + Quantizer Module kicks off a background job on ephemeral GPU resources."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Transformation: The raw model is converted into a TRT-LLM Checkpoint."}),"\n",(0,r.jsx)(n.li,{children:"Quantization: The system automatically applies quantization algorithms (like INT4 AWQ or FP8) to reduce memory footprint."}),"\n",(0,r.jsx)(n.li,{children:"Engine Building: Finally, it compiles a highly optimized TRT Engine specifically tuned for the target hardware."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Intelligent Profiling & Validation"}),"\n",(0,r.jsx)(n.p,{children:"Before deployment, the new engine passes through the Hardware & Inference Runtime Profiler."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Benchmarking: This module empirically tests the engine against various hardware configurations (L4 vs. A100) and runtimes (TRT-LLM vs. vLLM)."}),"\n",(0,r.jsx)(n.li,{children:"Optimization: It recommends the optimal configuration that meets latency SLAs (Time-To-First-Token) while minimizing cost."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Smart Artifact Generation & Distribution"}),"\n",(0,r.jsx)(n.p,{children:'To solve the Kubernetes "Cold Start" problem, the LLM Serving Artifacts Generation module packages the model using a bifurcated strategy:'}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Standard Models: Artifacts are uploaded to Cloud Storage (GCS) and downloaded by pods at startup."}),"\n",(0,r.jsx)(n.li,{children:"Very Large Models: For massive models (>8GB) where network downloads are too slow, the system pre-caches the model onto Secondary Boot Disks. These disks are attached directly to new GPU nodes during autoscaling, eliminating download wait times."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Image Streaming & Deployment"}),"\n",(0,r.jsx)(n.p,{children:"Simultaneously, the inference runtime container images are pulled from the Artifact Registry."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Image Streaming: We utilize container image streaming to allow pods to start initializing while the massive Triton/Dynamo container layers are still downloading, further shaving seconds off the startup time. link"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"The Inference Runtime (Kubernetes)"}),"\n",(0,r.jsx)(n.p,{children:"The workload lands on Kubernetes with Autoscaling."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Dynamic Backends: Depending on the profile generated in Stage 3, the pod initializes either TensorRT-LLM (for throughput) or vLLM (for flexibility), or spins up a Dynamo worker for distributed inference."}),"\n",(0,r.jsx)(n.li,{children:'Data Loading: The pod either downloads the model from Cloud Storage or mounts the pre-warmed Secondary Boot Disk ("Pull from Disk").'}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Client Interaction & Observability"}),"\n",(0,r.jsx)(n.p,{children:"Finally, the LLM Inference Client executes the request."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Prompt Injection: The client pulls the specific prompt template ID from the Registry, ensuring the exact versioned instructions are used."}),"\n",(0,r.jsx)(n.li,{children:"Streaming Response: The request is sent via gRPC, and tokens are streamed back to the user in real-time."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Observability: Monitoring the Pulse of GenAI"}),"\n",(0,r.jsx)(n.p,{children:"In traditional microservices, success is measured by CPU utilization and request latency (p99). For Large Language Models, these metrics are insufficient. A user doesn't care if the GPU is at 80% utilization; they care about how fast the first word appears and how smoothly the rest of the sentence follows."}),"\n",(0,r.jsx)(n.p,{children:"To capture the true user experience, our platform instrumentation focuses on three critical LLM-specific metrics:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Time to First Token (TTFT)"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Definition: TTFT measures the time elapsed from the moment a request is received until the very first token is generated and streamed back to the user."}),"\n",(0,r.jsx)(n.li,{children:'Why it matters: This represents the "Prefill Phase" latency\u2014the time the model takes to process the input prompt and load weights. A high TTFT makes the application feel unresponsive or "hung."'}),"\n",(0,r.jsx)(n.li,{children:"Optimization: We closely monitor TTFT to ensure our Prefix Caching is effective (aiming for high cache hitrates), which drastically lowers this metric by skipping redundant prompt processing."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Inter-Token Latency (ITL)"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:'Definition: ITL measures the average time interval between the generation of consecutive tokens during the "Decode Phase".'}),"\n",(0,r.jsx)(n.li,{children:'Why it matters: This defines the "perceived speed" of reading. Even if the first token is fast (low TTFT), high ITL makes the text generation look "jerky" or slow to the user.'}),"\n",(0,r.jsx)(n.li,{children:"Benchmarks: In our testing with Llama 3.1, we track p99 ITL to ensure it stays below human reading speeds to maintain a natural conversational flow."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Token Throughput vs. Request Throughput"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"We distinguish between two types of throughput to balance system efficiency with user load:"}),"\n",(0,r.jsx)(n.li,{children:"Token Throughput (tokens/sec): The total number of tokens generated across all concurrent requests. This measures the raw compute efficiency of the GPU and the effectiveness of batching."}),"\n",(0,r.jsx)(n.li,{children:"Request Throughput (req/sec): The number of distinct user queries served per second. We use this to determine autoscaling thresholds, ensuring we scale out before the queue depth impacts ITL."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"The Monitoring Stack"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:'Real-time Dashboards: We utilize Grafana to visualize these streaming metrics in real-time, allowing on-call engineers to spot "slow generation" incidents that generic "500 error" alerts would miss.'}),"\n",(0,r.jsx)(n.li,{children:'Request Tracing: Since Triton Inference Server does not log request payloads by default, we integrate a Helix Client to asynchronously publish request logs to Log Tables. This allows us to trace a specific "slow" request back to its prompt to understand if a complex input caused the latency spike.'}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"supported-inference-backends-tensorrt-llm--dynamo--vllm",children:"Supported Inference backends (TensorRT LLM, Dynamo & vLLM)"}),"\n",(0,r.jsx)(n.p,{children:'Tailored for the Use Case: We do not believe in a "one-size-fits-all" approach to inference. Different use cases\u2014whether a real-time voice bot requiring ultra-lowsub-second latency or a massive reasoning task requiring huge context windows\u2014demand different runtime characteristics. Our platform is designed to be runtime-agnostic, allowing us to automatically select and tailor the best engine based on the specific requirements of the application:'}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"TensorRT-LLM: The High-Performance Standard"}),"\n",(0,r.jsx)(n.p,{children:"Suitable for: High-throughput production workloads where latency is critical (e.g., customer support chat, real-time voice bots)."}),"\n",(0,r.jsx)(n.p,{children:"TensorRT-LLM serves as our default backend for these scenarios. Our internal benchmarks on Llama 3.1 and 3.2 models demonstrated that a tuned TensorRT-LLM engine significantly outperforms standard runtimes, especially when utilizing INT4 AWQ and FP8 quantization ."}),"\n",(0,r.jsx)(n.p,{children:"Key optimizations we tailor for these high-load cases include:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Optimized execution via TensorRT engine compilation"}),"\n",(0,r.jsx)(n.li,{children:"Quantization-aware execution for reduced memory usage and improved throughput"}),"\n",(0,r.jsx)(n.li,{children:"Inflight Batching: Allowing requests to be processed continuously without waiting for the entire batch to finish, drastically improving GPU utilization ."}),"\n",(0,r.jsx)(n.li,{children:"Custom Plugins: Enabling specific NVIDIA plugins like the GEMM plugin and GPT Attention plugin to accelerate matrix multiplications and attention mechanisms ."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Dynamo: Distributed Inference for Reasoning Models"}),"\n",(0,r.jsx)(n.p,{children:'Suitable for: Very large "reasoning" models (70B+) or scenarios requiring massive context windows where a single GPU\'s memory is insufficient.'}),"\n",(0,r.jsx)(n.p,{children:"For these memory-bound tasks, we utilize Dynamo, a low-latency distributed inference framework . Unlike monolithic servers, Dynamo disaggregates the inference process to scale resources horizontally:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"KV Aware Routing: A specialized router directs requests to workers that already hold the relevant Key-Value (KV) cache, minimizing redundant computation ."}),"\n",(0,r.jsx)(n.li,{children:'Prefill vs. Decode Split: The workload is divided into Prefill Workers (processing the prompt) and Decode Workers (generating tokens), allowing us to scale the compute-heavy "reading" phase independently from the memory-heavy "writing" phase .'}),"\n",(0,r.jsx)(n.li,{children:"Distributed execution across multiple GPU resources"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"vLLM: The Flexible Baseline"}),"\n",(0,r.jsx)(n.p,{children:"Suitable for: Rapid prototyping, testing new model architectures, or low-traffic internal tools where ease of deployment outweighs raw throughput."}),"\n",(0,r.jsx)(n.p,{children:"While TensorRT-LLM is optimized for maximum speed, vLLM provides a robust and flexible baseline ."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"High throughput through dynamic batching and efficient memory utilization"}),"\n",(0,r.jsx)(n.li,{children:"Paged KV cache management for handling long contexts and concurrent requests"}),"\n",(0,r.jsx)(n.li,{children:"Strong support for open-source model ecosystems"}),"\n",(0,r.jsx)(n.li,{children:"Rapid Adoption: It allows us to onboard new model architectures immediately without waiting for a custom TensorRT build."}),"\n",(0,r.jsx)(n.li,{children:"Benchmarking Insight: In our internal tests, vLLM provided a strong baseline but often lacked the specific max-token optimizations present in our custom TRT engines . We use it strategically for initial testing before committing to a full TensorRT optimization pipeline."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,r.jsx)(n.p,{children:"Large language model inference introduces a fundamentally new class of infrastructure challenges\u2014where performance is governed not just by raw compute, but by memory efficiency, intelligent scheduling, runtime specialization, and lifecycle automation. Unlike traditional ML serving, LLM inference requires systems that understand token-level execution, manage rapidly growing context state, and continuously balance latency, throughput, and cost under highly dynamic workloads."}),"\n",(0,r.jsx)(n.p,{children:"The LLM Inference Framework addresses these challenges by transforming inference into a fully automated, reproducible lifecycle\u2014from model onboarding and compilation to deployment, optimization, and observability. By integrating automated quantization and engine compilation, intelligent runtime selection, cold-start mitigation strategies, and LLM-specific observability metrics such as Time-to-First-Token and Inter-Token Latency, the platform ensures both high performance and operational simplicity."}),"\n",(0,r.jsx)(n.p,{children:"Equally important, the framework is designed with flexibility and future evolution in mind. Its runtime-agnostic architecture enables seamless adoption of emerging inference engines, hardware accelerators, and optimization techniques without requiring platform redesign. This ensures that teams can continuously leverage advancements in the rapidly evolving LLM ecosystem while maintaining consistent operational workflows."}),"\n",(0,r.jsx)(n.p,{children:"Ultimately, the goal of the platform is to make production-scale LLM deployment as seamless and reliable as traditional software deployment\u2014allowing teams to focus on building intelligent applications rather than managing infrastructure complexity. By combining lifecycle automation, runtime optimization, and deep observability, the LLM Inference Framework provides a scalable foundation for delivering fast, cost-efficient, and production-ready LLM experiences."}),"\n",(0,r.jsx)(n.h2,{id:"future-explorations",children:"Future Explorations"}),"\n",(0,r.jsx)(n.p,{children:"While we have achieved significant milestones in latency and throughput, the landscape of GenAI is evolving rapidly. Our roadmap focuses on increasing flexibility, reducing costs, and enhancing reliability for enterprise-grade workloads. Here is what we are building next:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"TPU Support: To diversify our hardware supply chain and further optimize cost-per-token, we are evaluating Google Cloud TPUs to bake it into our platform. By leveraging the JAX and PyTorch/XLA ecosystems, we aim to unlock the massive throughput potential of TPU v5e chips, particularly for our open-source Llama models. This will allow the hardware profiler to dynamically choose between NVIDIA GPUs and Google TPUs based on real-time availability and price-performance metrics."}),"\n",(0,r.jsx)(n.li,{children:'Multi-LoRA Serving (Serverless Experience): Currently, deploying a fine-tuned model requires a dedicated GPU. We are building support for Multi-LoRA serving, which will allow us to serve hundreds of unique, fine-tuned adapters on top of a single frozen base model. This will drastically reduce costs for multi-tenant applications, enabling a "serverless" experience where specific fine-tunes are hot-swapped instantly per request.'}),"\n",(0,r.jsx)(n.li,{children:"Spot Instance Orchestration: To further optimize cloud costs, we are developing fault-tolerant mechanisms to run inference workloads on Spot Instances. By implementing aggressive checkpointing and seamless request draining, we aim to leverage cheaper, preemptible compute capacity without interrupting the user's streaming experience."}),"\n",(0,r.jsx)(n.li,{children:'Semantic Caching Layer: We plan to move beyond standard Prefix Caching to implement Semantic Caching. By using a vector database to fetch responses for semantically similar queries (e.g., "How do I reset my password?" vs. "Password reset steps"), we can bypass the GPU entirely for repetitive queries, reducing latency to near-zero.'}),"\n",(0,r.jsx)(n.li,{children:"Context-Aware Autoscaling: Standard CPU/GPU utilization metrics are often insufficient signals for scaling LLMs. We are working on KV-cache pressure metrics for autoscaling. This ensures that we scale out before the memory fills up, preventing eviction-based slowdowns during traffic spikes."}),"\n",(0,r.jsx)(n.li,{children:'Online Evaluation & Guardrails: We are integrating a lightweight "Trust Layer" into the proxy. This will allow for low-latency input/output filtering (Guardrails) and asynchronous "LLM-as-a-Judge" evaluation pipelines to monitor response quality in production, not just system health.'}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},7996:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/bms-7399e8796d2cd24617c432518ce3f312.png"},8453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>o});var t=i(6540);const r={},s=t.createContext(r);function a(e){const n=t.useContext(s);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/7fa80e1c.78f6a21e.js b/docs/assets/js/7fa80e1c.78f6a21e.js new file mode 100644 index 00000000..07f71d30 --- /dev/null +++ b/docs/assets/js/7fa80e1c.78f6a21e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3322],{9189:a=>{a.exports=JSON.parse('{"tags":[{"label":"llm","permalink":"/BharatMLStack/blog/tags/llm","count":2},{"label":"vllm","permalink":"/BharatMLStack/blog/tags/vllm","count":2},{"label":"tensorrt-llm","permalink":"/BharatMLStack/blog/tags/tensorrt-llm","count":2},{"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform","count":5},{"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho","count":5},{"label":"bharatmlstack","permalink":"/BharatMLStack/blog/tags/bharatmlstack","count":4},{"label":"model-inference","permalink":"/BharatMLStack/blog/tags/model-inference","count":1},{"label":"embedding-search","permalink":"/BharatMLStack/blog/tags/embedding-search","count":1},{"label":"inferflow","permalink":"/BharatMLStack/blog/tags/inferflow","count":1},{"label":"interaction-store","permalink":"/BharatMLStack/blog/tags/interaction-store","count":2},{"label":"online-feature-store","permalink":"/BharatMLStack/blog/tags/online-feature-store","count":1}]}')}}]); \ No newline at end of file diff --git a/docs/assets/js/7fa80e1c.b5f726bf.js b/docs/assets/js/7fa80e1c.b5f726bf.js deleted file mode 100644 index 2761db28..00000000 --- a/docs/assets/js/7fa80e1c.b5f726bf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3322],{9189:a=>{a.exports=JSON.parse('{"tags":[{"label":"online-feature-store","permalink":"/BharatMLStack/blog/tags/online-feature-store","count":1},{"label":"interaction-store","permalink":"/BharatMLStack/blog/tags/interaction-store","count":1},{"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform","count":1},{"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho","count":1}]}')}}]); \ No newline at end of file diff --git a/docs/assets/js/814f3328.b45803b6.js b/docs/assets/js/814f3328.b45803b6.js deleted file mode 100644 index ad85a959..00000000 --- a/docs/assets/js/814f3328.b45803b6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7472],{5513:e=>{e.exports=JSON.parse('{"title":"Recent posts","items":[{"title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","permalink":"/BharatMLStack/blog/post-one","unlisted":false,"date":"2022-11-15T00:00:00.000Z"}]}')}}]); \ No newline at end of file diff --git a/docs/assets/js/814f3328.bfb123e8.js b/docs/assets/js/814f3328.bfb123e8.js new file mode 100644 index 00000000..f1e59d9a --- /dev/null +++ b/docs/assets/js/814f3328.bfb123e8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7472],{5513:e=>{e.exports=JSON.parse('{"title":"Recent posts","items":[{"title":"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale","permalink":"/BharatMLStack/blog/post-five","unlisted":false,"date":"2025-06-02T00:00:00.000Z"},{"title":"Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving","permalink":"/BharatMLStack/blog/post-three","unlisted":false,"date":"2025-03-29T00:00:00.000Z"},{"title":"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search","permalink":"/BharatMLStack/blog/post-three","unlisted":false,"date":"2024-05-21T00:00:00.000Z"},{"title":"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)","permalink":"/BharatMLStack/blog/post-two","unlisted":false,"date":"2023-04-10T00:00:00.000Z"},{"title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","permalink":"/BharatMLStack/blog/post-one","unlisted":false,"date":"2022-11-15T00:00:00.000Z"}]}')}}]); \ No newline at end of file diff --git a/docs/assets/js/8dd2df60.f10b075c.js b/docs/assets/js/8dd2df60.f10b075c.js new file mode 100644 index 00000000..98a10338 --- /dev/null +++ b/docs/assets/js/8dd2df60.f10b075c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1537],{3359:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Inferflow","description":"Inferflow is a graph-driven feature retrieval and model inference orchestration engine. It dynamically resolves entity relationships via configurable DAGs, retrieves features from the Online Feature Store, and orchestrates model scoring \u2014 all without custom code.","slug":"/category/inferflow","permalink":"/BharatMLStack/category/inferflow","sidebar":"tutorialSidebar","navigation":{"previous":{"title":"Release Notes","permalink":"/BharatMLStack/online-feature-store/v1.0.0/release-notes"},"next":{"title":"v1.0.0","permalink":"/BharatMLStack/inferflow/v1.0.0"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/8ea48c46.e52cd527.js b/docs/assets/js/8ea48c46.e52cd527.js new file mode 100644 index 00000000..00e31ec3 --- /dev/null +++ b/docs/assets/js/8ea48c46.e52cd527.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9824],{7956:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"numerix/v1.0.0/release-notes","title":"Release Notes","description":"Version 1.0.0 \ud83d\ude80","source":"@site/docs/numerix/v1.0.0/release-notes.md","sourceDirName":"numerix/v1.0.0","slug":"/numerix/v1.0.0/release-notes","permalink":"/BharatMLStack/numerix/v1.0.0/release-notes","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/numerix/v1.0.0/release-notes.md","tags":[],"version":"current","sidebarPosition":5,"frontMatter":{"title":"Release Notes","sidebar_position":5},"sidebar":"tutorialSidebar","previous":{"title":"Key Functionalities","permalink":"/BharatMLStack/numerix/v1.0.0/functionalities"}}');var r=i(4848),t=i(8453);const o={title:"Release Notes",sidebar_position:5},l="Numerix - Release Notes",a={},c=[{value:"Version 1.0.0 \ud83d\ude80",id:"version-100-",level:2},{value:"\ud83c\udfaf What's New",id:"-whats-new",level:2},{value:"Core Engine",id:"core-engine",level:3},{value:"API Surface",id:"api-surface",level:3},{value:"Observability",id:"observability",level:3},{value:"\ud83d\ude80 Performance & Optimization",id:"-performance--optimization",level:2},{value:"\ud83d\udee0\ufe0f APIs",id:"\ufe0f-apis",level:2},{value:"gRPC",id:"grpc",level:3},{value:"\ud83c\udfd7\ufe0f Deployment & Configuration",id:"\ufe0f-deployment--configuration",level:2},{value:"Environment",id:"environment",level:3},{value:"Containers",id:"containers",level:3},{value:"\ud83d\udd04 Compatibility",id:"-compatibility",level:2},{value:"\ud83d\udc1b Known Issues",id:"-known-issues",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"numerix---release-notes",children:"Numerix - Release Notes"})}),"\n",(0,r.jsx)(n.h2,{id:"version-100-",children:"Version 1.0.0 \ud83d\ude80"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Release Date"}),": September 2025",(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.strong,{children:"Status"}),": General Availability (GA)"]}),"\n",(0,r.jsxs)(n.p,{children:["The first stable release of ",(0,r.jsx)(n.strong,{children:"Numerix"})," \u2014 a Rust-based compute service for evaluating mathematical expressions over feature matrices with very low latency. Numerix executes postfix expressions from an etcd-backed registry using a stack-based evaluator and compiler-assisted SIMD."]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"-whats-new",children:"\ud83c\udfaf What's New"}),"\n",(0,r.jsx)(n.h3,{id:"core-engine",children:"Core Engine"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Postfix Expression Execution"}),": ",(0,r.jsx)(n.code,{children:"compute_id \u2192 postfix"})," mapping in etcd; parser-free request path."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Stack-Based Evaluator"}),": Linear-time execution over aligned vectors for predictable latency."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Compiler-Assisted SIMD"}),": Relies on LLVM autovectorization (NEON/SVE on ARM; SSE/AVX on x86); no handwritten intrinsics."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Typed Evaluation"}),": Internal conversion to ",(0,r.jsx)(n.code,{children:"fp32"}),"/",(0,r.jsx)(n.code,{children:"fp64"})," for consistent performance/precision."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"api-surface",children:"API Surface"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"gRPC"}),": Single RPC \u2014 ",(0,r.jsx)(n.code,{children:"numerix.Numerix/Compute"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Input Formats"}),": Strings for ease, bytes for performance; both map to vectorized math internally."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"observability",children:"Observability"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Datadog/DogStatsD"})," metrics: Latency (P50/P95/P99), RPS, error rate."]}),"\n",(0,r.jsxs)(n.li,{children:["Minimal HTTP diagnostics: ",(0,r.jsx)(n.code,{children:"/health"})," (and optional ",(0,r.jsx)(n.code,{children:"/metrics"}),")."]}),"\n"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"-performance--optimization",children:"\ud83d\ude80 Performance & Optimization"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Autovectorized Loops"}),": Tight loops over contiguous memory enable the compiler to emit SIMD instructions automatically."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"ARM Focus Option"}),": Excellent results with AArch64; builds can enable NEON/SVE/SVE2:"]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'RUSTFLAGS="-C target-feature=+neon,+sve,+sve2" \\\ncargo build --release --target aarch64-unknown-linux-gnu\n'})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Deterministic Runtime"}),": No dynamic parsing in hot path; O(n) across tokens with vectorized inner ops."]}),"\n"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"\ufe0f-apis",children:"\ud83d\udee0\ufe0f APIs"}),"\n",(0,r.jsx)(n.h3,{id:"grpc",children:"gRPC"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-protobuf",children:"service Numerix {\n rpc Compute(NumerixRequestProto) returns (NumerixResponseProto);\n}\n"})}),"\n",(0,r.jsx)(n.p,{children:"Example call:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'grpcurl -plaintext \\\n -import-path ./numerix/src/protos/proto \\\n -proto numerix.proto \\\n -d \'{\n "entityScoreData": {\n "schema": ["feature1", "feature2"],\n "entityScores": [ { "stringData": { "values": ["1.0", "2.0"] } } ],\n "computeId": "1001",\n "dataType": "fp32"\n }\n }\' \\\n localhost:8080 numerix.Numerix/Compute\n'})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"\ufe0f-deployment--configuration",children:"\ud83c\udfd7\ufe0f Deployment & Configuration"}),"\n",(0,r.jsx)(n.h3,{id:"environment",children:"Environment"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"APPLICATION_PORT=8083\nAPP_ENV=prd\nAPP_LOG_LEVEL=ERROR\nAPP_NAME=numerix\n\n# Performance\nCHANNEL_BUFFER_SIZE=10000\n\n# etcd\nETCD_SERVERS=127.0.0.1:2379\n\n# Metrics\nMETRIC_SAMPLING_RATE=1\nTELEGRAF_UDP_HOST=127.0.0.1\nTELEGRAF_UDP_PORT=8125\n"})}),"\n",(0,r.jsx)(n.h3,{id:"containers",children:"Containers"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Multi-arch images: ",(0,r.jsx)(n.code,{children:"linux/amd64"}),", ",(0,r.jsx)(n.code,{children:"linux/arm64"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["Build targets example: ",(0,r.jsx)(n.code,{children:"x86_64-unknown-linux-gnu"}),", ",(0,r.jsx)(n.code,{children:"aarch64-unknown-linux-gnu"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"-compatibility",children:"\ud83d\udd04 Compatibility"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Clients"}),": Any language with gRPC + generated stubs."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Architectures"}),": amd64 and arm64; ARM builds can enable NEON/SVE/SVE2."]}),"\n"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"-known-issues",children:"\ud83d\udc1b Known Issues"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Introduce a configurable log sampling rate to reduce pod memory usage during computation errors."}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,r.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,r.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\ud83d\udcac ",(0,r.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,r.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,r.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,r.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,r.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,r.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)("div",{align:"center",children:(0,r.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,r.jsx)("div",{align:"center",children:(0,r.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>l});var s=i(6540);const r={},t=s.createContext(r);function o(e){const n=s.useContext(t);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/93f344c7.7cebeb9e.js b/docs/assets/js/93f344c7.7cebeb9e.js new file mode 100644 index 00000000..2a74fffc --- /dev/null +++ b/docs/assets/js/93f344c7.7cebeb9e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4416],{5232:a=>{a.exports=JSON.parse('{"tag":{"label":"inferflow","permalink":"/BharatMLStack/blog/tags/inferflow","allTagsPath":"/BharatMLStack/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/BharatMLStack/blog/tags/inferflow","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/99009a21.1a57fa22.js b/docs/assets/js/99009a21.1a57fa22.js new file mode 100644 index 00000000..168befca --- /dev/null +++ b/docs/assets/js/99009a21.1a57fa22.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4064],{1161:t=>{t.exports=JSON.parse('{"tag":{"label":"tensorrt-llm","permalink":"/BharatMLStack/blog/tags/tensorrt-llm","allTagsPath":"/BharatMLStack/blog/tags","count":2,"unlisted":false},"listMetadata":{"permalink":"/BharatMLStack/blog/tags/tensorrt-llm","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/9aed321e.0ede45c0.js b/docs/assets/js/9aed321e.0ede45c0.js new file mode 100644 index 00000000..292183d0 --- /dev/null +++ b/docs/assets/js/9aed321e.0ede45c0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2951],{8453:(e,n,r)=>{r.d(n,{R:()=>l,x:()=>o});var i=r(6540);const s={},t=i.createContext(s);function l(e){const n=i.useContext(t);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),i.createElement(t.Provider,{value:n},e.children)}},9059:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"inferflow/v1.0.0/release-notes","title":"Release Notes","description":"Version 1.0.0","source":"@site/docs/inferflow/v1.0.0/release-notes.md","sourceDirName":"inferflow/v1.0.0","slug":"/inferflow/v1.0.0/release-notes","permalink":"/BharatMLStack/inferflow/v1.0.0/release-notes","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/inferflow/v1.0.0/release-notes.md","tags":[],"version":"current","sidebarPosition":4,"frontMatter":{"title":"Release Notes","sidebar_position":4},"sidebar":"tutorialSidebar","previous":{"title":"Configuration Guide","permalink":"/BharatMLStack/inferflow/v1.0.0/configuration"},"next":{"title":"Quick Start","permalink":"/BharatMLStack/category/quick-start"}}');var s=r(4848),t=r(8453);const l={title:"Release Notes",sidebar_position:4},o="Inferflow - Release Notes",d={},c=[{value:"Version 1.0.0",id:"version-100",level:2},{value:"What's New",id:"whats-new",level:2},{value:"Config-Driven DAG Executor",id:"config-driven-dag-executor",level:3},{value:"Multi-Pattern Inference APIs",id:"multi-pattern-inference-apis",level:3},{value:"Component System",id:"component-system",level:3},{value:"Online Feature Store Integration",id:"online-feature-store-integration",level:3},{value:"In-Memory Feature Caching",id:"in-memory-feature-caching",level:3},{value:"Inference Logging",id:"inference-logging",level:3},{value:"Performance",id:"performance",level:2},{value:"Built in Go",id:"built-in-go",level:3},{value:"Concurrency",id:"concurrency",level:3},{value:"Serialization",id:"serialization",level:3},{value:"APIs & Protocols",id:"apis--protocols",level:2},{value:"gRPC API",id:"grpc-api",level:3},{value:"Data Types Supported",id:"data-types-supported",level:3},{value:"Enterprise Features",id:"enterprise-features",level:2},{value:"Production Readiness",id:"production-readiness",level:3},{value:"Monitoring & Observability",id:"monitoring--observability",level:3},{value:"Configuration Management",id:"configuration-management",level:3},{value:"Deployment",id:"deployment",level:2},{value:"Container Support",id:"container-support",level:3},{value:"Supported Environments",id:"supported-environments",level:3},{value:"Compatibility",id:"compatibility",level:2},{value:"Supported Go Versions",id:"supported-go-versions",level:3},{value:"External Dependencies",id:"external-dependencies",level:3},{value:"Download & Installation",id:"download--installation",level:2},{value:"Source Code",id:"source-code",level:3},{value:"Build",id:"build",level:3},{value:"Docker",id:"docker",level:3},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"inferflow---release-notes",children:"Inferflow - Release Notes"})}),"\n",(0,s.jsx)(n.h2,{id:"version-100",children:"Version 1.0.0"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Release Date"}),": June 2025\n",(0,s.jsx)(n.strong,{children:"Status"}),": General Availability (GA)"]}),"\n",(0,s.jsxs)(n.p,{children:["We're excited to announce the first stable release of ",(0,s.jsx)(n.strong,{children:"Inferflow"})," \u2014 a graph-driven feature retrieval and model inference orchestration engine, part of BharatMLStack."]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"whats-new",children:"What's New"}),"\n",(0,s.jsx)(n.h3,{id:"config-driven-dag-executor",children:"Config-Driven DAG Executor"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"No-code feature retrieval"}),": Onboard new models with config changes only \u2014 no custom code required"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"DAG topology execution"}),": Define component dependency graphs that are executed concurrently using Kahn's algorithm"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Hot reload"}),": Model configurations stored in etcd are watched and reloaded live \u2014 no redeployment needed"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"DAG caching"}),": Topologies are cached using Murmur3 hashing with Ristretto for minimal overhead"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"multi-pattern-inference-apis",children:"Multi-Pattern Inference APIs"}),"\n",(0,s.jsx)(n.p,{children:"Three structured inference patterns via the Predict API:"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"API"}),(0,s.jsx)(n.th,{children:"Pattern"}),(0,s.jsx)(n.th,{children:"Use Case"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"InferPointWise"})}),(0,s.jsx)(n.td,{children:"Score each target independently"}),(0,s.jsx)(n.td,{children:"CTR prediction, fraud scoring"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"InferPairWise"})}),(0,s.jsx)(n.td,{children:"Score pairs of targets"}),(0,s.jsx)(n.td,{children:"Preference learning, comparison ranking"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"InferSlateWise"})}),(0,s.jsx)(n.td,{children:"Score groups of targets together"}),(0,s.jsx)(n.td,{children:"Whole-page optimization, diversity-aware ranking"})]})]})]}),"\n",(0,s.jsxs)(n.p,{children:["Plus the entity-based ",(0,s.jsx)(n.code,{children:"RetrieveModelScore"})," API for direct feature retrieval and scoring."]}),"\n",(0,s.jsx)(n.h3,{id:"component-system",children:"Component System"}),"\n",(0,s.jsx)(n.p,{children:"Four built-in component types:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"FeatureInitComponent"})," \u2014 Initializes the shared ComponentMatrix"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"FeatureComponent"})," \u2014 Fetches features from the Online Feature Store (OnFS)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"PredatorComponent"})," \u2014 Calls model serving endpoints with percentage-based traffic routing"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"NumerixComponent"})," \u2014 Calls compute engine for operations like reranking"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"online-feature-store-integration",children:"Online Feature Store Integration"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["gRPC-based feature retrieval via ",(0,s.jsx)(n.code,{children:"FeatureService.RetrieveFeatures"})]}),"\n",(0,s.jsx)(n.li,{children:"Batched retrieval with configurable batch size and deadline"}),"\n",(0,s.jsx)(n.li,{children:"Token-based authentication"}),"\n",(0,s.jsx)(n.li,{children:"Dynamic key resolution from the ComponentMatrix"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"in-memory-feature-caching",children:"In-Memory Feature Caching"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Optional per-component caching to reduce OnFS load"}),"\n",(0,s.jsx)(n.li,{children:"Configurable TTL per component"}),"\n",(0,s.jsx)(n.li,{children:"Zero-GC-overhead cache option (freecache)"}),"\n",(0,s.jsx)(n.li,{children:"Cache hit/miss metrics"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"inference-logging",children:"Inference Logging"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Async logging to Kafka for model monitoring and debugging"}),"\n",(0,s.jsxs)(n.li,{children:["Three serialization formats: ",(0,s.jsx)(n.strong,{children:"Proto"}),", ",(0,s.jsx)(n.strong,{children:"Arrow"}),", ",(0,s.jsx)(n.strong,{children:"Parquet"})]}),"\n",(0,s.jsx)(n.li,{children:"Configurable sampling rate and feature selection"}),"\n",(0,s.jsx)(n.li,{children:"Batched log message grouping"}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"performance",children:"Performance"}),"\n",(0,s.jsx)(n.h3,{id:"built-in-go",children:"Built in Go"}),"\n",(0,s.jsx)(n.p,{children:"Inferflow is written entirely in Go, delivering:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"~80% lower memory usage compared to equivalent Java services"}),"\n",(0,s.jsx)(n.li,{children:"Lower CPU utilization"}),"\n",(0,s.jsx)(n.li,{children:"Faster, more efficient deployments"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"concurrency",children:"Concurrency"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"DAG components at the same level execute concurrently in goroutines"}),"\n",(0,s.jsx)(n.li,{children:"Feature retrieval parallelized across entity types"}),"\n",(0,s.jsx)(n.li,{children:"Connection pooling for all external gRPC calls"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"serialization",children:"Serialization"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"gRPC with Proto3 for all APIs"}),"\n",(0,s.jsx)(n.li,{children:"Binary feature encoding in the ComponentMatrix"}),"\n",(0,s.jsx)(n.li,{children:"Configurable compression for Kafka logging (ZSTD support)"}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"apis--protocols",children:"APIs & Protocols"}),"\n",(0,s.jsx)(n.h3,{id:"grpc-api",children:"gRPC API"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Inferflow Service:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-protobuf",children:"service Inferflow {\n rpc RetrieveModelScore(InferflowRequestProto) returns (InferflowResponseProto);\n}\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Predict Service:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-protobuf",children:"service PredictService {\n rpc InferPointWise(PredictRequest) returns (PredictResponse);\n rpc InferPairWise(PredictRequest) returns (PredictResponse);\n rpc InferSlateWise(PredictRequest) returns (PredictResponse);\n}\n"})}),"\n",(0,s.jsx)(n.h3,{id:"data-types-supported",children:"Data Types Supported"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Variants"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Integers"}),(0,s.jsx)(n.td,{children:"int8, int16, int32, int64"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Floats"}),(0,s.jsx)(n.td,{children:"float8 (e4m3, e5m2), float16, float32, float64"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Strings"}),(0,s.jsx)(n.td,{children:"Variable length"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Booleans"}),(0,s.jsx)(n.td,{children:"Bit-packed"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Vectors"}),(0,s.jsx)(n.td,{children:"All scalar types"})]})]})]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"enterprise-features",children:"Enterprise Features"}),"\n",(0,s.jsx)(n.h3,{id:"production-readiness",children:"Production Readiness"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Health checks"}),": HTTP health endpoints via cmux"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Graceful shutdown"}),": Clean resource cleanup"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Structured logging"}),": JSON-formatted logs via zerolog"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Signal handling"}),": SIGTERM/SIGINT support for container environments"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"monitoring--observability",children:"Monitoring & Observability"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"StatsD / Telegraf integration"}),": Request rates, latencies, error rates"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Per-component metrics"}),": Execution time, feature counts, cache hit rates"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"External API metrics"}),": OnFS, Predator, Numerix call tracking"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Kafka logging metrics"}),": Messages sent, errors"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"configuration-management",children:"Configuration Management"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"etcd-based"}),": All model configs stored in etcd"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Watch & reload"}),": Live config updates without restart"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Multi-model support"}),": Multiple ",(0,s.jsx)(n.code,{children:"model_config_id"})," entries served concurrently"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"deployment",children:"Deployment"}),"\n",(0,s.jsx)(n.h3,{id:"container-support",children:"Container Support"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Docker image"}),": Multi-stage build (Go Alpine builder + Debian runtime)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Optional Kafka"}),": librdkafka support via build flag"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Static binary"}),": Single binary deployment"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"supported-environments",children:"Supported Environments"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Kubernetes (K8s)"}),"\n",(0,s.jsx)(n.li,{children:"Google Kubernetes Engine (GKE)"}),"\n",(0,s.jsx)(n.li,{children:"Amazon EKS"}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"compatibility",children:"Compatibility"}),"\n",(0,s.jsx)(n.h3,{id:"supported-go-versions",children:"Supported Go Versions"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Minimum"}),": Go 1.19"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Recommended"}),": Go 1.24+"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"external-dependencies",children:"External Dependencies"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Service"}),(0,s.jsx)(n.th,{children:"Version"}),(0,s.jsx)(n.th,{children:"Protocol"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"etcd"}),(0,s.jsx)(n.td,{children:"3.5+"}),(0,s.jsx)(n.td,{children:"gRPC"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Online Feature Store (OnFS)"}),(0,s.jsx)(n.td,{children:"1.0+"}),(0,s.jsx)(n.td,{children:"gRPC"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Predator (Helix)"}),(0,s.jsx)(n.td,{children:"1.0+"}),(0,s.jsx)(n.td,{children:"gRPC"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Numerix"}),(0,s.jsx)(n.td,{children:"1.0+"}),(0,s.jsx)(n.td,{children:"gRPC"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Kafka"}),(0,s.jsx)(n.td,{children:"2.0+"}),(0,s.jsx)(n.td,{children:"TCP"})]})]})]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"download--installation",children:"Download & Installation"}),"\n",(0,s.jsx)(n.h3,{id:"source-code",children:"Source Code"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/Meesho/BharatMLStack.git\ncd BharatMLStack/inferflow\n"})}),"\n",(0,s.jsx)(n.h3,{id:"build",children:"Build"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"go build -o inferflow-server cmd/inferflow/main.go\n"})}),"\n",(0,s.jsx)(n.h3,{id:"docker",children:"Docker"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker build -t inferflow:latest .\n"})}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,s.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,s.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,s.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,s.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,s.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)("div",{align:"center",children:(0,s.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,s.jsx)("div",{align:"center",children:(0,s.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}}}]); \ No newline at end of file diff --git a/docs/assets/js/9d13045e.3f255bd8.js b/docs/assets/js/9d13045e.3f255bd8.js new file mode 100644 index 00000000..c5b9c674 --- /dev/null +++ b/docs/assets/js/9d13045e.3f255bd8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8014],{7791:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>a,frontMatter:()=>c,metadata:()=>i,toc:()=>o});const i=JSON.parse('{"id":"inferflow/v1.0.0/configuration","title":"Configuration Guide","description":"Inferflow is fully config-driven. All model onboarding, feature retrieval logic, DAG topology, and inference behavior are controlled through configuration stored in etcd \u2014 with zero code changes required.","source":"@site/docs/inferflow/v1.0.0/configuration.md","sourceDirName":"inferflow/v1.0.0","slug":"/inferflow/v1.0.0/configuration","permalink":"/BharatMLStack/inferflow/v1.0.0/configuration","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/inferflow/v1.0.0/configuration.md","tags":[],"version":"current","sidebarPosition":3,"frontMatter":{"title":"Configuration Guide","sidebar_position":3},"sidebar":"tutorialSidebar","previous":{"title":"Key Functionalities","permalink":"/BharatMLStack/inferflow/v1.0.0/functionalities"},"next":{"title":"Release Notes","permalink":"/BharatMLStack/inferflow/v1.0.0/release-notes"}}');var s=r(4848),d=r(8453);const c={title:"Configuration Guide",sidebar_position:3},t="Inferflow - Configuration Guide",l={},o=[{value:"Configuration Overview",id:"configuration-overview",level:2},{value:"Static Configuration (Environment Variables)",id:"static-configuration-environment-variables",level:2},{value:"Server",id:"server",level:3},{value:"etcd",id:"etcd",level:3},{value:"Online Feature Store (OnFS)",id:"online-feature-store-onfs",level:3},{value:"Predator (Model Serving)",id:"predator-model-serving",level:3},{value:"Numerix (Compute Engine)",id:"numerix-compute-engine",level:3},{value:"Kafka (Inference Logging)",id:"kafka-inference-logging",level:3},{value:"Metrics (StatsD / Telegraf)",id:"metrics-statsd--telegraf",level:3},{value:"In-Memory Cache",id:"in-memory-cache",level:3},{value:"Dynamic Configuration (etcd Model Config)",id:"dynamic-configuration-etcd-model-config",level:2},{value:"Config Structure",id:"config-structure",level:3},{value:"DAG Execution Config",id:"dag-execution-config",level:3},{value:"Feature Component Config",id:"feature-component-config",level:3},{value:"Predator Component Config",id:"predator-component-config",level:3},{value:"Numerix Component Config",id:"numerix-component-config",level:3},{value:"Response Config",id:"response-config",level:3},{value:"Service-Level Config",id:"service-level-config",level:3},{value:"Example: Onboarding a New Model",id:"example-onboarding-a-new-model",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"inferflow---configuration-guide",children:"Inferflow - Configuration Guide"})}),"\n",(0,s.jsxs)(n.p,{children:["Inferflow is fully config-driven. All model onboarding, feature retrieval logic, DAG topology, and inference behavior are controlled through configuration stored in ",(0,s.jsx)(n.strong,{children:"etcd"})," \u2014 with zero code changes required."]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"configuration-overview",children:"Configuration Overview"}),"\n",(0,s.jsx)(n.p,{children:"Inferflow configuration is organized into two layers:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Static config"})," \u2014 Environment variables loaded at startup (via Viper)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Dynamic config"})," \u2014 Model configurations stored in etcd, hot-reloaded on change"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"static-configuration-environment-variables",children:"Static Configuration (Environment Variables)"}),"\n",(0,s.jsx)(n.p,{children:"These are set at deployment time and require a restart to change."}),"\n",(0,s.jsx)(n.h3,{id:"server",children:"Server"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable"}),(0,s.jsx)(n.th,{children:"Description"}),(0,s.jsx)(n.th,{children:"Example"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"APP_PORT"})}),(0,s.jsx)(n.td,{children:"gRPC/HTTP server port"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"50051"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"APP_ENV"})}),(0,s.jsx)(n.td,{children:"Environment name"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"production"})})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"etcd",children:"etcd"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable"}),(0,s.jsx)(n.th,{children:"Description"}),(0,s.jsx)(n.th,{children:"Example"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ETCD_ENDPOINTS"})}),(0,s.jsx)(n.td,{children:"Comma-separated etcd endpoints"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"etcd-0:2379,etcd-1:2379"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ETCD_DIAL_TIMEOUT"})}),(0,s.jsx)(n.td,{children:"Connection timeout"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"5s"})})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"online-feature-store-onfs",children:"Online Feature Store (OnFS)"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable"}),(0,s.jsx)(n.th,{children:"Description"}),(0,s.jsx)(n.th,{children:"Example"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"externalServiceOnFs_host"})}),(0,s.jsx)(n.td,{children:"OnFS gRPC host"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"onfs-api:50051"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"externalServiceOnFs_callerId"})}),(0,s.jsx)(n.td,{children:"Caller ID for auth"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"inferflow"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"externalServiceOnFs_callerToken"})}),(0,s.jsx)(n.td,{children:"Caller token for auth"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"<token>"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"externalServiceOnFs_batchSize"})}),(0,s.jsx)(n.td,{children:"Batch size for feature retrieval"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"100"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"externalServiceOnFs_deadline"})}),(0,s.jsx)(n.td,{children:"Request deadline"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"200ms"})})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"predator-model-serving",children:"Predator (Model Serving)"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable"}),(0,s.jsx)(n.th,{children:"Description"}),(0,s.jsx)(n.th,{children:"Example"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"externalServicePredator_defaultDeadline"})}),(0,s.jsx)(n.td,{children:"Default inference deadline"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"100ms"})})]})})]}),"\n",(0,s.jsx)(n.h3,{id:"numerix-compute-engine",children:"Numerix (Compute Engine)"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable"}),(0,s.jsx)(n.th,{children:"Description"}),(0,s.jsx)(n.th,{children:"Example"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"numerixClientV1_host"})}),(0,s.jsx)(n.td,{children:"Numerix gRPC host"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"numerix:50052"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"numerixClientV1_deadline"})}),(0,s.jsx)(n.td,{children:"Request deadline"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"100ms"})})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"kafka-inference-logging",children:"Kafka (Inference Logging)"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable"}),(0,s.jsx)(n.th,{children:"Description"}),(0,s.jsx)(n.th,{children:"Example"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"KafkaBootstrapServers"})}),(0,s.jsx)(n.td,{children:"Kafka broker addresses"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"kafka-0:9092,kafka-1:9092"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"KafkaLoggingTopic"})}),(0,s.jsx)(n.td,{children:"Topic for inference logs"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"inferflow-logs"})})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"metrics-statsd--telegraf",children:"Metrics (StatsD / Telegraf)"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable"}),(0,s.jsx)(n.th,{children:"Description"}),(0,s.jsx)(n.th,{children:"Example"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TELEGRAF_HOST"})}),(0,s.jsx)(n.td,{children:"StatsD host"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"telegraf"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TELEGRAF_PORT"})}),(0,s.jsx)(n.td,{children:"StatsD port"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"8125"})})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"in-memory-cache",children:"In-Memory Cache"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable"}),(0,s.jsx)(n.th,{children:"Description"}),(0,s.jsx)(n.th,{children:"Example"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"CACHE_SIZE_MB"})}),(0,s.jsx)(n.td,{children:"Cache size in MB"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"512"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"CACHE_TYPE"})}),(0,s.jsx)(n.td,{children:"Cache implementation"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"freecache"})})]})]})]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"dynamic-configuration-etcd-model-config",children:"Dynamic Configuration (etcd Model Config)"}),"\n",(0,s.jsxs)(n.p,{children:["Model configurations are stored in etcd and hot-reloaded. Each model is identified by a ",(0,s.jsx)(n.code,{children:"model_config_id"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"config-structure",children:"Config Structure"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "model_config_id_example": {\n "dag_execution_config": {\n "component_dependency": {\n "feature_initializer": ["fs_user", "fs_product"],\n "fs_user": ["ranker_model"],\n "fs_product": ["ranker_model"],\n "ranker_model": []\n }\n },\n "component_config": {\n "feature_component_config": {\n "fs_user": { ... },\n "fs_product": { ... }\n },\n "predator_component_config": {\n "ranker_model": { ... }\n },\n "numerix_component_config": {},\n "cache_enabled": true,\n "cache_version": "v1",\n "cache_ttl": 300,\n "error_logging_percent": 10\n },\n "response_config": {\n "features": ["ranker_model:score"],\n "model_schema_perc": 100,\n "logging_perc": 5,\n "log_features": ["fs_user:profile:age", "ranker_model:score"],\n "log_batch_size": 100\n }\n }\n}\n'})}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"dag-execution-config",children:"DAG Execution Config"}),"\n",(0,s.jsx)(n.p,{children:"Defines the component dependency graph."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "component_dependency": {\n "<parent_component>": ["<child_1>", "<child_2>"],\n "<child_1>": ["<grandchild>"],\n "<child_2>": ["<grandchild>"],\n "<grandchild>": []\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Rules:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The graph must be a valid DAG (no cycles)"}),"\n",(0,s.jsx)(n.li,{children:"Components with no parents (zero in-degree) execute first"}),"\n",(0,s.jsxs)(n.li,{children:["Components with empty dependency arrays ",(0,s.jsx)(n.code,{children:"[]"})," are leaf nodes"]}),"\n",(0,s.jsxs)(n.li,{children:["All component names must match registered components in the ",(0,s.jsx)(n.code,{children:"ComponentConfig"})]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"feature-component-config",children:"Feature Component Config"}),"\n",(0,s.jsx)(n.p,{children:"Configures how features are fetched from the Online Feature Store."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "fs_user": {\n "fs_keys": {\n "schema": ["user_id"],\n "col": "context:user:user_id"\n },\n "fs_request": {\n "entity_label": "user",\n "feature_groups": [\n {\n "label": "demographics",\n "feature_labels": ["age", "location", "income_bracket"]\n },\n {\n "label": "behavior",\n "feature_labels": ["click_rate", "purchase_freq"]\n }\n ]\n },\n "fs_flatten_resp_keys": ["user_id"],\n "col_name_prefix": "user",\n "comp_cache_enabled": true,\n "comp_cache_ttl": 600,\n "composite_id": false\n }\n}\n'})}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Field"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"fs_keys"})}),(0,s.jsxs)(n.td,{children:["How to extract lookup keys from the matrix. ",(0,s.jsx)(n.code,{children:"schema"})," defines key column names; ",(0,s.jsx)(n.code,{children:"col"})," references a matrix column"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"fs_request"})}),(0,s.jsx)(n.td,{children:"OnFS query: entity label + feature groups with specific features"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"fs_flatten_resp_keys"})}),(0,s.jsx)(n.td,{children:"Keys to flatten in response mapping"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"col_name_prefix"})}),(0,s.jsxs)(n.td,{children:["Prefix for matrix column names (e.g., ",(0,s.jsx)(n.code,{children:"user:demographics:age"}),")"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"comp_cache_enabled"})}),(0,s.jsx)(n.td,{children:"Enable in-memory caching for this component"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"comp_cache_ttl"})}),(0,s.jsx)(n.td,{children:"Cache TTL in seconds"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"composite_id"})}),(0,s.jsx)(n.td,{children:"Whether entity keys are composite"})]})]})]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"predator-component-config",children:"Predator Component Config"}),"\n",(0,s.jsx)(n.p,{children:"Configures model inference endpoints."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "ranker_model": {\n "model_name": "product_ranker_v3",\n "model_endpoint": "predator-ranker:8080",\n "model_end_points": {\n "predator-ranker-v3:8080": 80,\n "predator-ranker-v4:8080": 20\n },\n "deadline": 100,\n "batch_size": 50,\n "calibration": {\n "enabled": false\n },\n "inputs": {\n "feature_map": {\n "user:demographics:age": "INT32",\n "user:behavior:click_rate": "FP32",\n "product:attributes:category_id": "INT32"\n }\n },\n "outputs": {\n "score_columns": ["score", "confidence"]\n },\n "slate_component": false\n }\n}\n'})}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Field"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"model_name"})}),(0,s.jsx)(n.td,{children:"Model identifier on the serving platform"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"model_endpoint"})}),(0,s.jsx)(n.td,{children:"Primary model serving endpoint"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"model_end_points"})}),(0,s.jsx)(n.td,{children:"Multiple endpoints with percentage-based traffic routing"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"deadline"})}),(0,s.jsx)(n.td,{children:"Inference timeout in milliseconds"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"batch_size"})}),(0,s.jsx)(n.td,{children:"Max items per inference batch"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"calibration"})}),(0,s.jsx)(n.td,{children:"Score calibration settings"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"inputs.feature_map"})}),(0,s.jsx)(n.td,{children:"Map of matrix column \u2192 data type for model input"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"outputs.score_columns"})}),(0,s.jsx)(n.td,{children:"Column names for model output scores"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"slate_component"})}),(0,s.jsx)(n.td,{children:"If true, runs per-slate inference"})]})]})]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"numerix-component-config",children:"Numerix Component Config"}),"\n",(0,s.jsx)(n.p,{children:"Configures compute operations (e.g., reranking)."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "reranker": {\n "score_column": "final_score",\n "data_type": "FP32",\n "score_mapping": {\n "ranker_model:score": "FP32",\n "user:behavior:click_rate": "FP32"\n },\n "compute_id": "diversity_rerank_v1",\n "slate_component": false\n }\n}\n'})}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Field"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"score_column"})}),(0,s.jsx)(n.td,{children:"Output column name for the computed score"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"data_type"})}),(0,s.jsx)(n.td,{children:"Output data type"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"score_mapping"})}),(0,s.jsx)(n.td,{children:"Map of matrix columns to include as compute inputs"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"compute_id"})}),(0,s.jsx)(n.td,{children:"Identifies the compute operation on Numerix"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"slate_component"})}),(0,s.jsx)(n.td,{children:"If true, runs per-slate compute"})]})]})]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"response-config",children:"Response Config"}),"\n",(0,s.jsx)(n.p,{children:"Controls what data is returned to the client and what is logged."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "features": ["ranker_model:score", "reranker:final_score"],\n "model_schema_perc": 100,\n "logging_perc": 5,\n "log_features": [\n "user:demographics:age",\n "ranker_model:score",\n "reranker:final_score"\n ],\n "log_batch_size": 100\n}\n'})}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Field"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"features"})}),(0,s.jsx)(n.td,{children:"Matrix columns to include in the gRPC response"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"model_schema_perc"})}),(0,s.jsx)(n.td,{children:"Percentage of requests that include full schema in response"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"logging_perc"})}),(0,s.jsx)(n.td,{children:"Percentage of requests to send to Kafka for logging"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"log_features"})}),(0,s.jsx)(n.td,{children:"Specific features to include in log messages"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"log_batch_size"})}),(0,s.jsx)(n.td,{children:"Batch size for grouped log messages"})]})]})]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"service-level-config",children:"Service-Level Config"}),"\n",(0,s.jsx)(n.p,{children:"Global settings that apply across all models."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "v2_logging_type": "proto",\n "compression_enabled": false\n}\n'})}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Field"}),(0,s.jsx)(n.th,{children:"Values"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2_logging_type"})}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"proto"}),", ",(0,s.jsx)(n.code,{children:"arrow"}),", ",(0,s.jsx)(n.code,{children:"parquet"})]}),(0,s.jsx)(n.td,{children:"Serialization format for Kafka inference logs"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"compression_enabled"})}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"true"}),", ",(0,s.jsx)(n.code,{children:"false"})]}),(0,s.jsx)(n.td,{children:"Enable compression for log messages"})]})]})]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"example-onboarding-a-new-model",children:"Example: Onboarding a New Model"}),"\n",(0,s.jsx)(n.p,{children:"To onboard a new ranking model, update the etcd config:"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Step 1:"})," Define the feature retrieval graph"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"component_dependency": {\n "feature_initializer": ["fs_user", "fs_product", "fs_user_x_category"],\n "fs_product": ["fs_user_x_category"],\n "fs_user": ["new_ranker"],\n "fs_user_x_category": ["new_ranker"],\n "new_ranker": []\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Here ",(0,s.jsx)(n.code,{children:"fs_user_x_category"})," depends on ",(0,s.jsx)(n.code,{children:"fs_product"})," because it needs the category ID extracted from the product entity to resolve the user x category key."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Step 2:"})," Configure each component (feature groups, model endpoints, etc.)"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Step 3:"})," Push the config to etcd \u2014 Inferflow picks it up automatically via watchers."]}),"\n",(0,s.jsx)(n.p,{children:"No code changes. No redeployment. The new model is live."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,s.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,s.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,s.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,s.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,s.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)("div",{align:"center",children:(0,s.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,s.jsx)("div",{align:"center",children:(0,s.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function a(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},8453:(e,n,r)=>{r.d(n,{R:()=>c,x:()=>t});var i=r(6540);const s={},d=i.createContext(s);function c(e){const n=i.useContext(d);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),i.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/9e4087bc.342bf9bc.js b/docs/assets/js/9e4087bc.342bf9bc.js new file mode 100644 index 00000000..4364a70b --- /dev/null +++ b/docs/assets/js/9e4087bc.342bf9bc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2711],{6266:(e,r,a)=>{a.d(r,{i:()=>s});var t=a(4586);function s(e={}){const{i18n:{currentLocale:r}}=(0,t.A)(),a=function(){const{i18n:{currentLocale:e,localeConfigs:r}}=(0,t.A)();return r[e].calendar}();return new Intl.DateTimeFormat(r,{calendar:a,...e})}},9331:(e,r,a)=>{a.r(r),a.d(r,{default:()=>m});a(6540);var t=a(8774),s=a(1312),n=a(5500),i=a(6266),c=a(1656),l=a(1107),o=a(4848);function d({year:e,posts:r}){const a=(0,i.i)({day:"numeric",month:"long",timeZone:"UTC"});return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(l.A,{as:"h3",id:e,children:e}),(0,o.jsx)("ul",{children:r.map(e=>{return(0,o.jsx)("li",{children:(0,o.jsxs)(t.A,{to:e.metadata.permalink,children:[(r=e.metadata.date,a.format(new Date(r)))," - ",e.metadata.title]})},e.metadata.date);var r})})]})}function h({years:e}){return(0,o.jsx)("section",{className:"margin-vert--lg",children:(0,o.jsx)("div",{className:"container",children:(0,o.jsx)("div",{className:"row",children:e.map((e,r)=>(0,o.jsx)("div",{className:"col col--4 margin-vert--lg",children:(0,o.jsx)(d,{...e})},r))})})})}function m({archive:e}){const r=(0,s.T)({id:"theme.blog.archive.title",message:"Archive",description:"The page & hero title of the blog archive page"}),a=(0,s.T)({id:"theme.blog.archive.description",message:"Archive",description:"The page & hero description of the blog archive page"}),t=function(e){const r=e.reduce((e,r)=>{const a=r.metadata.date.split("-")[0],t=e.get(a)??[];return e.set(a,[r,...t])},new Map);return Array.from(r,([e,r])=>({year:e,posts:r}))}(e.blogPosts);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.be,{title:r,description:a}),(0,o.jsxs)(c.A,{children:[(0,o.jsx)("header",{className:"hero hero--primary",children:(0,o.jsxs)("div",{className:"container",children:[(0,o.jsx)(l.A,{as:"h1",className:"hero__title",children:r}),(0,o.jsx)("p",{className:"hero__subtitle",children:a})]})}),(0,o.jsx)("main",{children:t.length>0&&(0,o.jsx)(h,{years:t})})]})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/9e4087bc.b154716b.js b/docs/assets/js/9e4087bc.b154716b.js deleted file mode 100644 index 9a388f81..00000000 --- a/docs/assets/js/9e4087bc.b154716b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2711],{6266:(e,r,a)=>{a.d(r,{i:()=>s});var t=a(4586);function s(e={}){const{i18n:{currentLocale:r}}=(0,t.A)(),a=function(){const{i18n:{currentLocale:e,localeConfigs:r}}=(0,t.A)();return r[e].calendar}();return new Intl.DateTimeFormat(r,{calendar:a,...e})}},9331:(e,r,a)=>{a.r(r),a.d(r,{default:()=>m});a(6540);var t=a(8774),s=a(1312),n=a(5500),i=a(6266),c=a(1656),l=a(1107),o=a(4848);function d({year:e,posts:r}){const a=(0,i.i)({day:"numeric",month:"long",timeZone:"UTC"});return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(l.A,{as:"h3",id:e,children:e}),(0,o.jsx)("ul",{children:r.map((e=>{return(0,o.jsx)("li",{children:(0,o.jsxs)(t.A,{to:e.metadata.permalink,children:[(r=e.metadata.date,a.format(new Date(r)))," - ",e.metadata.title]})},e.metadata.date);var r}))})]})}function h({years:e}){return(0,o.jsx)("section",{className:"margin-vert--lg",children:(0,o.jsx)("div",{className:"container",children:(0,o.jsx)("div",{className:"row",children:e.map(((e,r)=>(0,o.jsx)("div",{className:"col col--4 margin-vert--lg",children:(0,o.jsx)(d,{...e})},r)))})})})}function m({archive:e}){const r=(0,s.T)({id:"theme.blog.archive.title",message:"Archive",description:"The page & hero title of the blog archive page"}),a=(0,s.T)({id:"theme.blog.archive.description",message:"Archive",description:"The page & hero description of the blog archive page"}),t=function(e){const r=e.reduce(((e,r)=>{const a=r.metadata.date.split("-")[0],t=e.get(a)??[];return e.set(a,[r,...t])}),new Map);return Array.from(r,(([e,r])=>({year:e,posts:r})))}(e.blogPosts);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.be,{title:r,description:a}),(0,o.jsxs)(c.A,{children:[(0,o.jsx)("header",{className:"hero hero--primary",children:(0,o.jsxs)("div",{className:"container",children:[(0,o.jsx)(l.A,{as:"h1",className:"hero__title",children:r}),(0,o.jsx)("p",{className:"hero__subtitle",children:a})]})}),(0,o.jsx)("main",{children:t.length>0&&(0,o.jsx)(h,{years:t})})]})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/a6aa9e1f.a34fe105.js b/docs/assets/js/a6aa9e1f.a34fe105.js deleted file mode 100644 index 05cd3173..00000000 --- a/docs/assets/js/a6aa9e1f.a34fe105.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7643],{2053:(e,t,a)=>{a.d(t,{A:()=>o});a(6540);var n=a(4164),s=a(1312),r=a(6133);const i={tags:"tags_jXut",tag:"tag_QGVx"};var l=a(4848);function o({tags:e}){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("b",{children:(0,l.jsx)(s.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,l.jsx)("ul",{className:(0,n.A)(i.tags,"padding--none","margin-left--sm"),children:e.map((e=>(0,l.jsx)("li",{className:i.tag,children:(0,l.jsx)(r.A,{...e})},e.permalink)))})]})}},2907:(e,t,a)=>{a.d(t,{A:()=>U});a(6540);var n=a(4164),s=a(4096),r=a(4848);function i({children:e,className:t}){return(0,r.jsx)("article",{className:t,children:e})}var l=a(8774);const o={title:"title_f1Hy"};function c({className:e}){const{metadata:t,isBlogPostPage:a}=(0,s.e7)(),{permalink:i,title:c}=t,d=a?"h1":"h2";return(0,r.jsx)(d,{className:(0,n.A)(o.title,e),children:a?c:(0,r.jsx)(l.A,{to:i,children:c})})}var d=a(1312),g=a(5846),m=a(6266);const u={container:"container_mt6G"};function h({readingTime:e}){const t=function(){const{selectMessage:e}=(0,g.W)();return t=>{const a=Math.ceil(t);return e(a,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:a}))}}();return(0,r.jsx)(r.Fragment,{children:t(e)})}function p({date:e,formattedDate:t}){return(0,r.jsx)("time",{dateTime:e,children:t})}function x(){return(0,r.jsx)(r.Fragment,{children:" \xb7 "})}function j({className:e}){const{metadata:t}=(0,s.e7)(),{date:a,readingTime:i}=t,l=(0,m.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,r.jsxs)("div",{className:(0,n.A)(u.container,"margin-vert--md",e),children:[(0,r.jsx)(p,{date:a,formattedDate:(o=a,l.format(new Date(o)))}),void 0!==i&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(x,{}),(0,r.jsx)(h,{readingTime:i})]})]});var o}var A=a(6382);const b={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function f({className:e}){const{metadata:{authors:t},assets:a}=(0,s.e7)();if(0===t.length)return null;const i=t.every((({name:e})=>!e)),l=1===t.length;return(0,r.jsx)("div",{className:(0,n.A)("margin-top--md margin-bottom--sm",i?b.imageOnlyAuthorRow:"row",e),children:t.map(((e,t)=>(0,r.jsx)("div",{className:(0,n.A)(!i&&(l?"col col--12":"col col--6"),i?b.imageOnlyAuthorCol:b.authorCol),children:(0,r.jsx)(A.A,{author:{...e,imageURL:a.authorsImageUrls[t]??e.imageURL}})},t)))})}function v(){return(0,r.jsxs)("header",{children:[(0,r.jsx)(c,{}),(0,r.jsx)(j,{}),(0,r.jsx)(f,{})]})}var N=a(440),_=a(3253);function T({children:e,className:t}){const{isBlogPostPage:a}=(0,s.e7)();return(0,r.jsx)("div",{id:a?N.LU:void 0,className:(0,n.A)("markdown",t),children:(0,r.jsx)(_.A,{children:e})})}var k=a(7559),w=a(4336),y=a(2053);function P(){return(0,r.jsx)("b",{children:(0,r.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function R(e){const{blogPostTitle:t,...a}=e;return(0,r.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...a,children:(0,r.jsx)(P,{})})}function C(){const{metadata:e,isBlogPostPage:t}=(0,s.e7)(),{tags:a,title:i,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,g=!t&&o,m=a.length>0;if(!(m||g||l))return null;if(t){const e=!!(l||d||c);return(0,r.jsxs)("footer",{className:"docusaurus-mt-lg",children:[m&&(0,r.jsx)("div",{className:(0,n.A)("row","margin-top--sm",k.G.blog.blogFooterEditMetaRow),children:(0,r.jsx)("div",{className:"col",children:(0,r.jsx)(y.A,{tags:a})})}),e&&(0,r.jsx)(w.A,{className:(0,n.A)("margin-top--sm",k.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,r.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[m&&(0,r.jsx)("div",{className:(0,n.A)("col",{"col--9":g}),children:(0,r.jsx)(y.A,{tags:a})}),g&&(0,r.jsx)("div",{className:(0,n.A)("col text--right",{"col--3":m}),children:(0,r.jsx)(R,{blogPostTitle:i,to:e.permalink})})]})}function U({children:e,className:t}){const a=function(){const{isBlogPostPage:e}=(0,s.e7)();return e?void 0:"margin-bottom--xl"}();return(0,r.jsxs)(i,{className:(0,n.A)(a,t),children:[(0,r.jsx)(v,{}),(0,r.jsx)(T,{children:e}),(0,r.jsx)(C,{})]})}},3892:(e,t,a)=>{a.d(t,{A:()=>i});a(6540);var n=a(4096),s=a(2907),r=a(4848);function i({items:e,component:t=s.A}){return(0,r.jsx)(r.Fragment,{children:e.map((({content:e})=>(0,r.jsx)(n.in,{content:e,children:(0,r.jsx)(t,{children:(0,r.jsx)(e,{})})},e.metadata.permalink)))})}},5124:(e,t,a)=>{a.r(t),a.d(t,{default:()=>j});a(6540);var n=a(4164),s=a(4586),r=a(5500),i=a(7559),l=a(8027),o=a(7713),c=a(1463),d=a(3892),g=a(5260),m=a(4096),u=a(4848);function h(e){const t=(0,m.kJ)(e);return(0,u.jsx)(g.A,{children:(0,u.jsx)("script",{type:"application/ld+json",children:JSON.stringify(t)})})}function p(e){const{metadata:t}=e,{siteConfig:{title:a}}=(0,s.A)(),{blogDescription:n,blogTitle:i,permalink:l}=t,o="/"===l?a:i;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(r.be,{title:o,description:n}),(0,u.jsx)(c.A,{tag:"blog_posts_list"})]})}function x(e){const{metadata:t,items:a,sidebar:n}=e;return(0,u.jsxs)(l.A,{sidebar:n,children:[(0,u.jsx)(d.A,{items:a}),(0,u.jsx)(o.A,{metadata:t})]})}function j(e){return(0,u.jsxs)(r.e3,{className:(0,n.A)(i.G.wrapper.blogPages,i.G.page.blogListPage),children:[(0,u.jsx)(p,{...e}),(0,u.jsx)(h,{...e}),(0,u.jsx)(x,{...e})]})}},6133:(e,t,a)=>{a.d(t,{A:()=>l});a(6540);var n=a(4164),s=a(8774);const r={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var i=a(4848);function l({permalink:e,label:t,count:a,description:l}){return(0,i.jsxs)(s.A,{rel:"tag",href:e,title:l,className:(0,n.A)(r.tag,a?r.tagWithCount:r.tagRegular),children:[t,a&&(0,i.jsx)("span",{children:a})]})}},7713:(e,t,a)=>{a.d(t,{A:()=>i});a(6540);var n=a(1312),s=a(9022),r=a(4848);function i(e){const{metadata:t}=e,{previousPage:a,nextPage:i}=t;return(0,r.jsxs)("nav",{className:"pagination-nav","aria-label":(0,n.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[a&&(0,r.jsx)(s.A,{permalink:a,title:(0,r.jsx)(n.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer entries"})}),i&&(0,r.jsx)(s.A,{permalink:i,title:(0,r.jsx)(n.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older entries"}),isNext:!0})]})}},9022:(e,t,a)=>{a.d(t,{A:()=>i});a(6540);var n=a(4164),s=a(8774),r=a(4848);function i(e){const{permalink:t,title:a,subLabel:i,isNext:l}=e;return(0,r.jsxs)(s.A,{className:(0,n.A)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[i&&(0,r.jsx)("div",{className:"pagination-nav__sublabel",children:i}),(0,r.jsx)("div",{className:"pagination-nav__label",children:a})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/a6aa9e1f.e531d6c8.js b/docs/assets/js/a6aa9e1f.e531d6c8.js new file mode 100644 index 00000000..3cc9c0b0 --- /dev/null +++ b/docs/assets/js/a6aa9e1f.e531d6c8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7643],{2053:(e,t,a)=>{a.d(t,{A:()=>o});a(6540);var n=a(4164),s=a(1312),r=a(6133);const i={tags:"tags_jXut",tag:"tag_QGVx"};var l=a(4848);function o({tags:e}){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("b",{children:(0,l.jsx)(s.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,l.jsx)("ul",{className:(0,n.A)(i.tags,"padding--none","margin-left--sm"),children:e.map(e=>(0,l.jsx)("li",{className:i.tag,children:(0,l.jsx)(r.A,{...e})},e.permalink))})]})}},2907:(e,t,a)=>{a.d(t,{A:()=>U});a(6540);var n=a(4164),s=a(4096),r=a(4848);function i({children:e,className:t}){return(0,r.jsx)("article",{className:t,children:e})}var l=a(8774);const o={title:"title_f1Hy"};function c({className:e}){const{metadata:t,isBlogPostPage:a}=(0,s.e7)(),{permalink:i,title:c}=t,d=a?"h1":"h2";return(0,r.jsx)(d,{className:(0,n.A)(o.title,e),children:a?c:(0,r.jsx)(l.A,{to:i,children:c})})}var d=a(1312),g=a(5846),m=a(6266);const u={container:"container_mt6G"};function h({readingTime:e}){const t=function(){const{selectMessage:e}=(0,g.W)();return t=>{const a=Math.ceil(t);return e(a,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:a}))}}();return(0,r.jsx)(r.Fragment,{children:t(e)})}function p({date:e,formattedDate:t}){return(0,r.jsx)("time",{dateTime:e,children:t})}function x(){return(0,r.jsx)(r.Fragment,{children:" \xb7 "})}function j({className:e}){const{metadata:t}=(0,s.e7)(),{date:a,readingTime:i}=t,l=(0,m.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,r.jsxs)("div",{className:(0,n.A)(u.container,"margin-vert--md",e),children:[(0,r.jsx)(p,{date:a,formattedDate:(o=a,l.format(new Date(o)))}),void 0!==i&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(x,{}),(0,r.jsx)(h,{readingTime:i})]})]});var o}var A=a(6382);const b={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function f({className:e}){const{metadata:{authors:t},assets:a}=(0,s.e7)();if(0===t.length)return null;const i=t.every(({name:e})=>!e),l=1===t.length;return(0,r.jsx)("div",{className:(0,n.A)("margin-top--md margin-bottom--sm",i?b.imageOnlyAuthorRow:"row",e),children:t.map((e,t)=>(0,r.jsx)("div",{className:(0,n.A)(!i&&(l?"col col--12":"col col--6"),i?b.imageOnlyAuthorCol:b.authorCol),children:(0,r.jsx)(A.A,{author:{...e,imageURL:a.authorsImageUrls[t]??e.imageURL}})},t))})}function v(){return(0,r.jsxs)("header",{children:[(0,r.jsx)(c,{}),(0,r.jsx)(j,{}),(0,r.jsx)(f,{})]})}var N=a(440),_=a(3253);function T({children:e,className:t}){const{isBlogPostPage:a}=(0,s.e7)();return(0,r.jsx)("div",{id:a?N.LU:void 0,className:(0,n.A)("markdown",t),children:(0,r.jsx)(_.A,{children:e})})}var k=a(7559),w=a(4336),y=a(2053);function P(){return(0,r.jsx)("b",{children:(0,r.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function R(e){const{blogPostTitle:t,...a}=e;return(0,r.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...a,children:(0,r.jsx)(P,{})})}function C(){const{metadata:e,isBlogPostPage:t}=(0,s.e7)(),{tags:a,title:i,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,g=!t&&o,m=a.length>0;if(!(m||g||l))return null;if(t){const e=!!(l||d||c);return(0,r.jsxs)("footer",{className:"docusaurus-mt-lg",children:[m&&(0,r.jsx)("div",{className:(0,n.A)("row","margin-top--sm",k.G.blog.blogFooterEditMetaRow),children:(0,r.jsx)("div",{className:"col",children:(0,r.jsx)(y.A,{tags:a})})}),e&&(0,r.jsx)(w.A,{className:(0,n.A)("margin-top--sm",k.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,r.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[m&&(0,r.jsx)("div",{className:(0,n.A)("col",{"col--9":g}),children:(0,r.jsx)(y.A,{tags:a})}),g&&(0,r.jsx)("div",{className:(0,n.A)("col text--right",{"col--3":m}),children:(0,r.jsx)(R,{blogPostTitle:i,to:e.permalink})})]})}function U({children:e,className:t}){const a=function(){const{isBlogPostPage:e}=(0,s.e7)();return e?void 0:"margin-bottom--xl"}();return(0,r.jsxs)(i,{className:(0,n.A)(a,t),children:[(0,r.jsx)(v,{}),(0,r.jsx)(T,{children:e}),(0,r.jsx)(C,{})]})}},3892:(e,t,a)=>{a.d(t,{A:()=>i});a(6540);var n=a(4096),s=a(2907),r=a(4848);function i({items:e,component:t=s.A}){return(0,r.jsx)(r.Fragment,{children:e.map(({content:e})=>(0,r.jsx)(n.in,{content:e,children:(0,r.jsx)(t,{children:(0,r.jsx)(e,{})})},e.metadata.permalink))})}},5124:(e,t,a)=>{a.r(t),a.d(t,{default:()=>j});a(6540);var n=a(4164),s=a(4586),r=a(5500),i=a(7559),l=a(8027),o=a(7713),c=a(1463),d=a(3892),g=a(5260),m=a(4096),u=a(4848);function h(e){const t=(0,m.kJ)(e);return(0,u.jsx)(g.A,{children:(0,u.jsx)("script",{type:"application/ld+json",children:JSON.stringify(t)})})}function p(e){const{metadata:t}=e,{siteConfig:{title:a}}=(0,s.A)(),{blogDescription:n,blogTitle:i,permalink:l}=t,o="/"===l?a:i;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(r.be,{title:o,description:n}),(0,u.jsx)(c.A,{tag:"blog_posts_list"})]})}function x(e){const{metadata:t,items:a,sidebar:n}=e;return(0,u.jsxs)(l.A,{sidebar:n,children:[(0,u.jsx)(d.A,{items:a}),(0,u.jsx)(o.A,{metadata:t})]})}function j(e){return(0,u.jsxs)(r.e3,{className:(0,n.A)(i.G.wrapper.blogPages,i.G.page.blogListPage),children:[(0,u.jsx)(p,{...e}),(0,u.jsx)(h,{...e}),(0,u.jsx)(x,{...e})]})}},6133:(e,t,a)=>{a.d(t,{A:()=>l});a(6540);var n=a(4164),s=a(8774);const r={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var i=a(4848);function l({permalink:e,label:t,count:a,description:l}){return(0,i.jsxs)(s.A,{rel:"tag",href:e,title:l,className:(0,n.A)(r.tag,a?r.tagWithCount:r.tagRegular),children:[t,a&&(0,i.jsx)("span",{children:a})]})}},7713:(e,t,a)=>{a.d(t,{A:()=>i});a(6540);var n=a(1312),s=a(9022),r=a(4848);function i(e){const{metadata:t}=e,{previousPage:a,nextPage:i}=t;return(0,r.jsxs)("nav",{className:"pagination-nav","aria-label":(0,n.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[a&&(0,r.jsx)(s.A,{permalink:a,title:(0,r.jsx)(n.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer entries"})}),i&&(0,r.jsx)(s.A,{permalink:i,title:(0,r.jsx)(n.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older entries"}),isNext:!0})]})}},9022:(e,t,a)=>{a.d(t,{A:()=>i});a(6540);var n=a(4164),s=a(8774),r=a(4848);function i(e){const{permalink:t,title:a,subLabel:i,isNext:l}=e;return(0,r.jsxs)(s.A,{className:(0,n.A)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[i&&(0,r.jsx)("div",{className:"pagination-nav__sublabel",children:i}),(0,r.jsx)("div",{className:"pagination-nav__label",children:a})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/a94703ab.3a38a667.js b/docs/assets/js/a94703ab.3a38a667.js new file mode 100644 index 00000000..dbe14b8d --- /dev/null +++ b/docs/assets/js/a94703ab.3a38a667.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9048],{1377:(e,t,n)=>{n.r(t),n.d(t,{default:()=>pe});var a=n(6540),o=n(4164),i=n(5500),s=n(7559),r=n(6972),c=n(609),l=n(1312),d=n(3104),u=n(5062);const m={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};var b=n(4848);function h(){const{shown:e,scrollToTop:t}=function({threshold:e}){const[t,n]=(0,a.useState)(!1),o=(0,a.useRef)(!1),{startScroll:i,cancelScroll:s}=(0,d.gk)();return(0,d.Mq)(({scrollY:t},a)=>{const i=a?.scrollY;i&&(o.current?o.current=!1:t>=i?(s(),n(!1)):t<e?n(!1):t+window.innerHeight<document.documentElement.scrollHeight&&n(!0))}),(0,u.$)(e=>{e.location.hash&&(o.current=!0,n(!1))}),{shown:t,scrollToTop:()=>i(0)}}({threshold:300});return(0,b.jsx)("button",{"aria-label":(0,l.T)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,o.A)("clean-btn",s.G.common.backToTopButton,m.backToTopButton,e&&m.backToTopButtonShow),type:"button",onClick:t})}var p=n(3109),x=n(6347),f=n(4581),j=n(6342),v=n(3465);function _(e){return(0,b.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,b.jsxs)("g",{fill:"#7a7a7a",children:[(0,b.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,b.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const g="collapseSidebarButton_PEFL",A="collapseSidebarButtonIcon_kv0_";function C({onClick:e}){return(0,b.jsx)("button",{type:"button",title:(0,l.T)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,l.T)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,o.A)("button button--secondary button--outline",g),onClick:e,children:(0,b.jsx)(_,{className:A})})}var k=n(5041),S=n(9532);const T=Symbol("EmptyContext"),N=a.createContext(T);function I({children:e}){const[t,n]=(0,a.useState)(null),o=(0,a.useMemo)(()=>({expandedItem:t,setExpandedItem:n}),[t]);return(0,b.jsx)(N.Provider,{value:o,children:e})}var y=n(1422),B=n(9169),w=n(8774),L=n(2303);function E({collapsed:e,categoryLabel:t,onClick:n}){return(0,b.jsx)("button",{"aria-label":e?(0,l.T)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:t}):(0,l.T)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:t}),"aria-expanded":!e,type:"button",className:"clean-btn menu__caret",onClick:n})}function M({item:e,onItemClick:t,activePath:n,level:i,index:c,...l}){const{items:d,label:u,collapsible:m,className:h,href:p}=e,{docs:{sidebar:{autoCollapseCategories:x}}}=(0,j.p)(),f=function(e){const t=(0,L.A)();return(0,a.useMemo)(()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,r.Nr)(e):void 0,[e,t])}(e),v=(0,r.w8)(e,n),_=(0,B.ys)(p,n),{collapsed:g,setCollapsed:A}=(0,y.u)({initialState:()=>!!m&&(!v&&e.collapsed)}),{expandedItem:C,setExpandedItem:k}=function(){const e=(0,a.useContext)(N);if(e===T)throw new S.dV("DocSidebarItemsExpandedStateProvider");return e}(),I=(e=!g)=>{k(e?null:c),A(e)};return function({isActive:e,collapsed:t,updateCollapsed:n}){const o=(0,S.ZC)(e);(0,a.useEffect)(()=>{e&&!o&&t&&n(!1)},[e,o,t,n])}({isActive:v,collapsed:g,updateCollapsed:I}),(0,a.useEffect)(()=>{m&&null!=C&&C!==c&&x&&A(!0)},[m,C,c,A,x]),(0,b.jsxs)("li",{className:(0,o.A)(s.G.docs.docSidebarItemCategory,s.G.docs.docSidebarItemCategoryLevel(i),"menu__list-item",{"menu__list-item--collapsed":g},h),children:[(0,b.jsxs)("div",{className:(0,o.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":_}),children:[(0,b.jsx)(w.A,{className:(0,o.A)("menu__link",{"menu__link--sublist":m,"menu__link--sublist-caret":!p&&m,"menu__link--active":v}),onClick:m?n=>{t?.(e),p?_?(n.preventDefault(),I()):I(!1):(n.preventDefault(),I())}:()=>{t?.(e)},"aria-current":_?"page":void 0,role:m&&!p?"button":void 0,"aria-expanded":m&&!p?!g:void 0,href:m?f??"#":f,...l,children:u}),p&&m&&(0,b.jsx)(E,{collapsed:g,categoryLabel:u,onClick:e=>{e.preventDefault(),I()}})]}),(0,b.jsx)(y.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:g,children:(0,b.jsx)(V,{items:d,tabIndex:g?-1:0,onItemClick:t,activePath:n,level:i+1})})]})}var H=n(6654),G=n(3186);const P="menuExternalLink_NmtK";function R({item:e,onItemClick:t,activePath:n,level:a,index:i,...c}){const{href:l,label:d,className:u,autoAddBaseUrl:m}=e,h=(0,r.w8)(e,n),p=(0,H.A)(l);return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(a),"menu__list-item",u),children:(0,b.jsxs)(w.A,{className:(0,o.A)("menu__link",!p&&P,{"menu__link--active":h}),autoAddBaseUrl:m,"aria-current":h?"page":void 0,to:l,...p&&{onClick:t?()=>t(e):void 0},...c,children:[d,!p&&(0,b.jsx)(G.A,{})]})},d)}const W="menuHtmlItem_M9Kj";function D({item:e,level:t,index:n}){const{value:a,defaultStyle:i,className:r}=e;return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(t),i&&[W,"menu__list-item"],r),dangerouslySetInnerHTML:{__html:a}},n)}function F({item:e,...t}){switch(e.type){case"category":return(0,b.jsx)(M,{item:e,...t});case"html":return(0,b.jsx)(D,{item:e,...t});default:return(0,b.jsx)(R,{item:e,...t})}}function U({items:e,...t}){const n=(0,r.Y)(e,t.activePath);return(0,b.jsx)(I,{children:n.map((e,n)=>(0,b.jsx)(F,{item:e,index:n,...t},n))})}const V=(0,a.memo)(U),Y="menu_SIkG",K="menuWithAnnouncementBar_GW3s";function z({path:e,sidebar:t,className:n}){const i=function(){const{isActive:e}=(0,k.M)(),[t,n]=(0,a.useState)(e);return(0,d.Mq)(({scrollY:t})=>{e&&n(0===t)},[e]),e&&t}();return(0,b.jsx)("nav",{"aria-label":(0,l.T)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,o.A)("menu thin-scrollbar",Y,i&&K,n),children:(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(V,{items:t,activePath:e,level:1})})})}const q="sidebar_njMd",O="sidebarWithHideableNavbar_wUlq",J="sidebarHidden_VK0M",Q="sidebarLogo_isFc";function X({path:e,sidebar:t,onCollapse:n,isHidden:a}){const{navbar:{hideOnScroll:i},docs:{sidebar:{hideable:s}}}=(0,j.p)();return(0,b.jsxs)("div",{className:(0,o.A)(q,i&&O,a&&J),children:[i&&(0,b.jsx)(v.A,{tabIndex:-1,className:Q}),(0,b.jsx)(z,{path:e,sidebar:t}),s&&(0,b.jsx)(C,{onClick:n})]})}const Z=a.memo(X);var $=n(5600),ee=n(9876);const te=({sidebar:e,path:t})=>{const n=(0,ee.M)();return(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(V,{items:e,activePath:t,onItemClick:e=>{"category"===e.type&&e.href&&n.toggle(),"link"===e.type&&n.toggle()},level:1})})};function ne(e){return(0,b.jsx)($.GX,{component:te,props:e})}const ae=a.memo(ne);function oe(e){const t=(0,f.l)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,b.jsxs)(b.Fragment,{children:[n&&(0,b.jsx)(Z,{...e}),a&&(0,b.jsx)(ae,{...e})]})}const ie={expandButton:"expandButton_TmdG",expandButtonIcon:"expandButtonIcon_i1dp"};function se({toggleSidebar:e}){return(0,b.jsx)("div",{className:ie.expandButton,title:(0,l.T)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,l.T)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:e,onClick:e,children:(0,b.jsx)(_,{className:ie.expandButtonIcon})})}const re={docSidebarContainer:"docSidebarContainer_YfHR",docSidebarContainerHidden:"docSidebarContainerHidden_DPk8",sidebarViewport:"sidebarViewport_aRkj"};function ce({children:e}){const t=(0,c.t)();return(0,b.jsx)(a.Fragment,{children:e},t?.name??"noSidebar")}function le({sidebar:e,hiddenSidebarContainer:t,setHiddenSidebarContainer:n}){const{pathname:i}=(0,x.zy)(),[r,c]=(0,a.useState)(!1),l=(0,a.useCallback)(()=>{r&&c(!1),!r&&(0,p.O)()&&c(!0),n(e=>!e)},[n,r]);return(0,b.jsx)("aside",{className:(0,o.A)(s.G.docs.docSidebarContainer,re.docSidebarContainer,t&&re.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(re.docSidebarContainer)&&t&&c(!0)},children:(0,b.jsx)(ce,{children:(0,b.jsxs)("div",{className:(0,o.A)(re.sidebarViewport,r&&re.sidebarViewportHidden),children:[(0,b.jsx)(oe,{sidebar:e,path:i,onCollapse:l,isHidden:r}),r&&(0,b.jsx)(se,{toggleSidebar:l})]})})})}const de={docMainContainer:"docMainContainer_TBSr",docMainContainerEnhanced:"docMainContainerEnhanced_lQrH",docItemWrapperEnhanced:"docItemWrapperEnhanced_JWYK"};function ue({hiddenSidebarContainer:e,children:t}){const n=(0,c.t)();return(0,b.jsx)("main",{className:(0,o.A)(de.docMainContainer,(e||!n)&&de.docMainContainerEnhanced),children:(0,b.jsx)("div",{className:(0,o.A)("container padding-top--md padding-bottom--lg",de.docItemWrapper,e&&de.docItemWrapperEnhanced),children:t})})}const me={docRoot:"docRoot_UBD9",docsWrapper:"docsWrapper_hBAB"};function be({children:e}){const t=(0,c.t)(),[n,o]=(0,a.useState)(!1);return(0,b.jsxs)("div",{className:me.docsWrapper,children:[(0,b.jsx)(h,{}),(0,b.jsxs)("div",{className:me.docRoot,children:[t&&(0,b.jsx)(le,{sidebar:t.items,hiddenSidebarContainer:n,setHiddenSidebarContainer:o}),(0,b.jsx)(ue,{hiddenSidebarContainer:n,children:e})]})]})}var he=n(3363);function pe(e){const t=(0,r.B5)(e);if(!t)return(0,b.jsx)(he.A,{});const{docElement:n,sidebarName:a,sidebarItems:l}=t;return(0,b.jsx)(i.e3,{className:(0,o.A)(s.G.page.docsDocPage),children:(0,b.jsx)(c.V,{name:a,items:l,children:(0,b.jsx)(be,{children:n})})})}},3363:(e,t,n)=>{n.d(t,{A:()=>r});n(6540);var a=n(4164),o=n(1312),i=n(1107),s=n(4848);function r({className:e}){return(0,s.jsx)("main",{className:(0,a.A)("container margin-vert--xl",e),children:(0,s.jsx)("div",{className:"row",children:(0,s.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,s.jsx)(i.A,{as:"h1",className:"hero__title",children:(0,s.jsx)(o.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/a94703ab.50a268a2.js b/docs/assets/js/a94703ab.50a268a2.js deleted file mode 100644 index 331a960f..00000000 --- a/docs/assets/js/a94703ab.50a268a2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9048],{1377:(e,t,n)=>{n.r(t),n.d(t,{default:()=>pe});var a=n(6540),o=n(4164),i=n(5500),s=n(7559),r=n(6972),c=n(609),l=n(1312),d=n(3104),u=n(5062);const m={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};var b=n(4848);function h(){const{shown:e,scrollToTop:t}=function({threshold:e}){const[t,n]=(0,a.useState)(!1),o=(0,a.useRef)(!1),{startScroll:i,cancelScroll:s}=(0,d.gk)();return(0,d.Mq)((({scrollY:t},a)=>{const i=a?.scrollY;i&&(o.current?o.current=!1:t>=i?(s(),n(!1)):t<e?n(!1):t+window.innerHeight<document.documentElement.scrollHeight&&n(!0))})),(0,u.$)((e=>{e.location.hash&&(o.current=!0,n(!1))})),{shown:t,scrollToTop:()=>i(0)}}({threshold:300});return(0,b.jsx)("button",{"aria-label":(0,l.T)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,o.A)("clean-btn",s.G.common.backToTopButton,m.backToTopButton,e&&m.backToTopButtonShow),type:"button",onClick:t})}var p=n(3109),x=n(6347),f=n(4581),j=n(6342),v=n(3465);function _(e){return(0,b.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,b.jsxs)("g",{fill:"#7a7a7a",children:[(0,b.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,b.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const g="collapseSidebarButton_PEFL",A="collapseSidebarButtonIcon_kv0_";function C({onClick:e}){return(0,b.jsx)("button",{type:"button",title:(0,l.T)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,l.T)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,o.A)("button button--secondary button--outline",g),onClick:e,children:(0,b.jsx)(_,{className:A})})}var k=n(5041),S=n(9532);const T=Symbol("EmptyContext"),N=a.createContext(T);function I({children:e}){const[t,n]=(0,a.useState)(null),o=(0,a.useMemo)((()=>({expandedItem:t,setExpandedItem:n})),[t]);return(0,b.jsx)(N.Provider,{value:o,children:e})}var y=n(1422),B=n(9169),w=n(8774),L=n(2303);function E({collapsed:e,categoryLabel:t,onClick:n}){return(0,b.jsx)("button",{"aria-label":e?(0,l.T)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:t}):(0,l.T)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:t}),"aria-expanded":!e,type:"button",className:"clean-btn menu__caret",onClick:n})}function M({item:e,onItemClick:t,activePath:n,level:i,index:c,...l}){const{items:d,label:u,collapsible:m,className:h,href:p}=e,{docs:{sidebar:{autoCollapseCategories:x}}}=(0,j.p)(),f=function(e){const t=(0,L.A)();return(0,a.useMemo)((()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,r.Nr)(e):void 0),[e,t])}(e),v=(0,r.w8)(e,n),_=(0,B.ys)(p,n),{collapsed:g,setCollapsed:A}=(0,y.u)({initialState:()=>!!m&&(!v&&e.collapsed)}),{expandedItem:C,setExpandedItem:k}=function(){const e=(0,a.useContext)(N);if(e===T)throw new S.dV("DocSidebarItemsExpandedStateProvider");return e}(),I=(e=!g)=>{k(e?null:c),A(e)};return function({isActive:e,collapsed:t,updateCollapsed:n}){const o=(0,S.ZC)(e);(0,a.useEffect)((()=>{e&&!o&&t&&n(!1)}),[e,o,t,n])}({isActive:v,collapsed:g,updateCollapsed:I}),(0,a.useEffect)((()=>{m&&null!=C&&C!==c&&x&&A(!0)}),[m,C,c,A,x]),(0,b.jsxs)("li",{className:(0,o.A)(s.G.docs.docSidebarItemCategory,s.G.docs.docSidebarItemCategoryLevel(i),"menu__list-item",{"menu__list-item--collapsed":g},h),children:[(0,b.jsxs)("div",{className:(0,o.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":_}),children:[(0,b.jsx)(w.A,{className:(0,o.A)("menu__link",{"menu__link--sublist":m,"menu__link--sublist-caret":!p&&m,"menu__link--active":v}),onClick:m?n=>{t?.(e),p?_?(n.preventDefault(),I()):I(!1):(n.preventDefault(),I())}:()=>{t?.(e)},"aria-current":_?"page":void 0,role:m&&!p?"button":void 0,"aria-expanded":m&&!p?!g:void 0,href:m?f??"#":f,...l,children:u}),p&&m&&(0,b.jsx)(E,{collapsed:g,categoryLabel:u,onClick:e=>{e.preventDefault(),I()}})]}),(0,b.jsx)(y.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:g,children:(0,b.jsx)(V,{items:d,tabIndex:g?-1:0,onItemClick:t,activePath:n,level:i+1})})]})}var H=n(6654),G=n(3186);const P="menuExternalLink_NmtK";function R({item:e,onItemClick:t,activePath:n,level:a,index:i,...c}){const{href:l,label:d,className:u,autoAddBaseUrl:m}=e,h=(0,r.w8)(e,n),p=(0,H.A)(l);return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(a),"menu__list-item",u),children:(0,b.jsxs)(w.A,{className:(0,o.A)("menu__link",!p&&P,{"menu__link--active":h}),autoAddBaseUrl:m,"aria-current":h?"page":void 0,to:l,...p&&{onClick:t?()=>t(e):void 0},...c,children:[d,!p&&(0,b.jsx)(G.A,{})]})},d)}const W="menuHtmlItem_M9Kj";function D({item:e,level:t,index:n}){const{value:a,defaultStyle:i,className:r}=e;return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(t),i&&[W,"menu__list-item"],r),dangerouslySetInnerHTML:{__html:a}},n)}function F({item:e,...t}){switch(e.type){case"category":return(0,b.jsx)(M,{item:e,...t});case"html":return(0,b.jsx)(D,{item:e,...t});default:return(0,b.jsx)(R,{item:e,...t})}}function U({items:e,...t}){const n=(0,r.Y)(e,t.activePath);return(0,b.jsx)(I,{children:n.map(((e,n)=>(0,b.jsx)(F,{item:e,index:n,...t},n)))})}const V=(0,a.memo)(U),Y="menu_SIkG",K="menuWithAnnouncementBar_GW3s";function z({path:e,sidebar:t,className:n}){const i=function(){const{isActive:e}=(0,k.M)(),[t,n]=(0,a.useState)(e);return(0,d.Mq)((({scrollY:t})=>{e&&n(0===t)}),[e]),e&&t}();return(0,b.jsx)("nav",{"aria-label":(0,l.T)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,o.A)("menu thin-scrollbar",Y,i&&K,n),children:(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(V,{items:t,activePath:e,level:1})})})}const q="sidebar_njMd",O="sidebarWithHideableNavbar_wUlq",J="sidebarHidden_VK0M",Q="sidebarLogo_isFc";function X({path:e,sidebar:t,onCollapse:n,isHidden:a}){const{navbar:{hideOnScroll:i},docs:{sidebar:{hideable:s}}}=(0,j.p)();return(0,b.jsxs)("div",{className:(0,o.A)(q,i&&O,a&&J),children:[i&&(0,b.jsx)(v.A,{tabIndex:-1,className:Q}),(0,b.jsx)(z,{path:e,sidebar:t}),s&&(0,b.jsx)(C,{onClick:n})]})}const Z=a.memo(X);var $=n(5600),ee=n(9876);const te=({sidebar:e,path:t})=>{const n=(0,ee.M)();return(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(V,{items:e,activePath:t,onItemClick:e=>{"category"===e.type&&e.href&&n.toggle(),"link"===e.type&&n.toggle()},level:1})})};function ne(e){return(0,b.jsx)($.GX,{component:te,props:e})}const ae=a.memo(ne);function oe(e){const t=(0,f.l)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,b.jsxs)(b.Fragment,{children:[n&&(0,b.jsx)(Z,{...e}),a&&(0,b.jsx)(ae,{...e})]})}const ie={expandButton:"expandButton_TmdG",expandButtonIcon:"expandButtonIcon_i1dp"};function se({toggleSidebar:e}){return(0,b.jsx)("div",{className:ie.expandButton,title:(0,l.T)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,l.T)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:e,onClick:e,children:(0,b.jsx)(_,{className:ie.expandButtonIcon})})}const re={docSidebarContainer:"docSidebarContainer_YfHR",docSidebarContainerHidden:"docSidebarContainerHidden_DPk8",sidebarViewport:"sidebarViewport_aRkj"};function ce({children:e}){const t=(0,c.t)();return(0,b.jsx)(a.Fragment,{children:e},t?.name??"noSidebar")}function le({sidebar:e,hiddenSidebarContainer:t,setHiddenSidebarContainer:n}){const{pathname:i}=(0,x.zy)(),[r,c]=(0,a.useState)(!1),l=(0,a.useCallback)((()=>{r&&c(!1),!r&&(0,p.O)()&&c(!0),n((e=>!e))}),[n,r]);return(0,b.jsx)("aside",{className:(0,o.A)(s.G.docs.docSidebarContainer,re.docSidebarContainer,t&&re.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(re.docSidebarContainer)&&t&&c(!0)},children:(0,b.jsx)(ce,{children:(0,b.jsxs)("div",{className:(0,o.A)(re.sidebarViewport,r&&re.sidebarViewportHidden),children:[(0,b.jsx)(oe,{sidebar:e,path:i,onCollapse:l,isHidden:r}),r&&(0,b.jsx)(se,{toggleSidebar:l})]})})})}const de={docMainContainer:"docMainContainer_TBSr",docMainContainerEnhanced:"docMainContainerEnhanced_lQrH",docItemWrapperEnhanced:"docItemWrapperEnhanced_JWYK"};function ue({hiddenSidebarContainer:e,children:t}){const n=(0,c.t)();return(0,b.jsx)("main",{className:(0,o.A)(de.docMainContainer,(e||!n)&&de.docMainContainerEnhanced),children:(0,b.jsx)("div",{className:(0,o.A)("container padding-top--md padding-bottom--lg",de.docItemWrapper,e&&de.docItemWrapperEnhanced),children:t})})}const me={docRoot:"docRoot_UBD9",docsWrapper:"docsWrapper_hBAB"};function be({children:e}){const t=(0,c.t)(),[n,o]=(0,a.useState)(!1);return(0,b.jsxs)("div",{className:me.docsWrapper,children:[(0,b.jsx)(h,{}),(0,b.jsxs)("div",{className:me.docRoot,children:[t&&(0,b.jsx)(le,{sidebar:t.items,hiddenSidebarContainer:n,setHiddenSidebarContainer:o}),(0,b.jsx)(ue,{hiddenSidebarContainer:n,children:e})]})]})}var he=n(3363);function pe(e){const t=(0,r.B5)(e);if(!t)return(0,b.jsx)(he.A,{});const{docElement:n,sidebarName:a,sidebarItems:l}=t;return(0,b.jsx)(i.e3,{className:(0,o.A)(s.G.page.docsDocPage),children:(0,b.jsx)(c.V,{name:a,items:l,children:(0,b.jsx)(be,{children:n})})})}},3363:(e,t,n)=>{n.d(t,{A:()=>r});n(6540);var a=n(4164),o=n(1312),i=n(1107),s=n(4848);function r({className:e}){return(0,s.jsx)("main",{className:(0,a.A)("container margin-vert--xl",e),children:(0,s.jsx)("div",{className:"row",children:(0,s.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,s.jsx)(i.A,{as:"h1",className:"hero__title",children:(0,s.jsx)(o.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/a97f18d9.ce4ddba2.js b/docs/assets/js/a97f18d9.ce4ddba2.js new file mode 100644 index 00000000..c6af68cd --- /dev/null +++ b/docs/assets/js/a97f18d9.ce4ddba2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6724],{1106:e=>{e.exports=JSON.parse('{"permalink":"/BharatMLStack/blog/post-two","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-two/index.md","source":"@site/blog/bharatmlstack-history/post-two/index.md","title":"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)","description":"BharatMLStack","date":"2023-04-10T00:00:00.000Z","tags":[{"inline":true,"label":"inferflow","permalink":"/BharatMLStack/blog/tags/inferflow"},{"inline":true,"label":"interaction-store","permalink":"/BharatMLStack/blog/tags/interaction-store"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"},{"inline":true,"label":"bharatmlstack","permalink":"/BharatMLStack/blog/tags/bharatmlstack"}],"readingTime":6.31,"hasTruncateMarker":false,"authors":[{"name":"Bhawani Singh","title":"Architect @ Meesho","url":"https://github.com/singh-bhawani","imageURL":"https://github.com/singh-bhawani.png","key":"bhawani","page":null},{"name":"Jigar Dave","title":"Lead Software Engineer @ Meesho","url":"https://github.com/jigarpatel26","imageURL":"https://github.com/jigarpatel26.png","key":"jigar","page":null},{"name":"Adarsha Das","title":"Senior Architect @ Meesho","url":"https://github.com/a0d00kc","imageURL":"https://github.com/a0d00kc.png","key":"adarsha","page":null}],"frontMatter":{"slug":"post-two","title":"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)","authors":["bhawani","jigar","adarsha"],"date":"2023-4-10","tags":["inferflow","interaction-store","mlplatform","meesho","bharatmlstack"]},"unlisted":false,"prevItem":{"title":"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search","permalink":"/BharatMLStack/blog/post-three"},"nextItem":{"title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","permalink":"/BharatMLStack/blog/post-one"}}')},3086:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/bms-7399e8796d2cd24617c432518ce3f312.png"},4114:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/mp-dag-976ff51caf25f09d977ccc10e70918f3.png"},4215:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var i=t(1106),r=t(4848),s=t(8453);const a={slug:"post-two",title:"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)",authors:["bhawani","jigar","adarsha"],date:"2023-4-10",tags:["inferflow","interaction-store","mlplatform","meesho","bharatmlstack"]},o=void 0,l={authorsImageUrls:[void 0,void 0,void 0]},c=[{value:"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)",id:"building-meeshos-ml-platform-lessons-from-the-first-gen-system-part-2",level:2},{value:"The Cost of Success",id:"the-cost-of-success",level:3},{value:"Scaling Pains (and Cassandra\u2019s Limits)",id:"scaling-pains-and-cassandras-limits",level:3},{value:"Interaction Store Woes",id:"interaction-store-woes",level:3},{value:"Silver Linings",id:"silver-linings",level:3},{value:"Round Two: Solving the Top 2 Bottlenecks",id:"round-two-solving-the-top-2-bottlenecks",level:3},{value:"Problem 1: No-Code Feature Retrieval for Model Inference",id:"problem-1-no-code-feature-retrieval-for-model-inference",level:4},{value:"Problem 2: Scaling Without Breaking the Bank",id:"problem-2-scaling-without-breaking-the-bank",level:4},{value:"Optimizing the Online Feature Store",id:"optimizing-the-online-feature-store",level:4},{value:"Optimizing the Interaction Store",id:"optimizing-the-interaction-store",level:4},{value:"Results",id:"results",level:4},{value:"The Catch: Our ML Hosting Hit a Hard Limit",id:"the-catch-our-ml-hosting-hit-a-hard-limit",level:4},{value:"Conclusion: From Firefighting to Future-Proofing",id:"conclusion-from-firefighting-to-future-proofing",level:3}];function d(e){const n={h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",ol:"ol",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"BharatMLStack",src:t(3086).A+"",width:"1396",height:"460"})}),"\n",(0,r.jsx)(n.h2,{id:"building-meeshos-ml-platform-lessons-from-the-first-gen-system-part-2",children:"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)"}),"\n",(0,r.jsx)(n.p,{children:"By late 2022, we had built something we were truly proud of\u2014a real-time ML serving system with a DAG-based executor, a feature store, and an interaction store powering key ranking and personalization models. It was a major milestone, the culmination of months of effort from data scientists, ML engineers, and backend teams. Our system was live, and we were ready to push the boundaries of experimentation.\nAnd it worked. Mostly.\nBut soon, cracks appeared. Every new model needed custom feature retrieval logic, DAGs became dense and unmanageable, and scaling turned into a constant firefight. Costs surged, and infra bottlenecks slowed experimentation. Our system worked, but it wasn\u2019t built for scale.\nThis is the story of how we tackled these challenges\u2014building Inferflow for seamless feature retrieval, optimizing real-time infra, and cutting costs while scaling to millions of QPS."}),"\n",(0,r.jsx)(n.h3,{id:"the-cost-of-success",children:"The Cost of Success"}),"\n",(0,r.jsx)(n.p,{children:"Every new Ranker model required its own feature set, often pulling from different entities. Each addition meant:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Adding new DAG nodes in IOP"}),"\n",(0,r.jsx)(n.li,{children:"Writing custom logic to fetch features from multiple sources (e.g., user, product, user \xd7 category)"}),"\n",(0,r.jsx)(n.li,{children:"Inferring intermediate features (e.g., extracting category from a product to fetch user \xd7 category data)"}),"\n",(0,r.jsx)(n.li,{children:"Optimizing I/O and dealing with the inevitable bugs"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"What began as clean DAGs soon turned into a tangled web of cross-dependent graphs. Every experimentation cycle meant new nodes, new dependencies, and slower iterations."}),"\n",(0,r.jsx)(n.h3,{id:"scaling-pains-and-cassandras-limits",children:"Scaling Pains (and Cassandra\u2019s Limits)"}),"\n",(0,r.jsx)(n.p,{children:"At some point, we were hitting:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"250\u2013300K reads/sec"}),"\n",(0,r.jsx)(n.li,{children:"1M writes/sec (during lean hours)"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"All of this ran on Cassandra. While its distributed architecture had been proven in production, operating large-scale clusters came with considerable infrastructure overhead. Our proof-of-concept (POC) demonstrated throughput of around 100K ops/sec, but as we scaled further, the challenges grew. Ensuring node health, optimizing compaction, and maintaining storage balance became increasingly demanding. We also observed latency spikes under heavy load, alongside a sharp increase in total cost of ownership."}),"\n",(0,r.jsx)(n.h3,{id:"interaction-store-woes",children:"Interaction Store Woes"}),"\n",(0,r.jsx)(n.p,{children:"Our interaction store was another ticking time bomb:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\ud83d\udea8 Clusters kept growing in size and cost"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\udea8 Latency spikes became increasingly frequent"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\udea8 The DMC proxy occasionally lost locality of nodes against shards, causing cross-node communication and degraded performance"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Each time this happened, we had to manually rebalance shards just to restore stable latency, making operations unsustainable at scale."}),"\n",(0,r.jsx)(n.h3,{id:"silver-linings",children:"Silver Linings"}),"\n",(0,r.jsx)(n.p,{children:"Despite the chaos, the system was live and delivering value:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Real-time infrastructure was in production"}),"\n",(0,r.jsx)(n.li,{children:"Costs dropped by 60\u201370% compared to offline personalization"}),"\n",(0,r.jsx)(n.li,{children:"New experiments rolled out faster and more successfully"}),"\n",(0,r.jsx)(n.li,{children:"User engagement metrics improved"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"It wasn\u2019t perfect. It was far from easy. But it worked\u2014and that counted for a lot."}),"\n",(0,r.jsx)(n.h3,{id:"round-two-solving-the-top-2-bottlenecks",children:"Round Two: Solving the Top 2 Bottlenecks"}),"\n",(0,r.jsx)(n.p,{children:"With the first-gen system stretched to its limits, we stepped back. Conversations with data scientists and backend engineers revealed three recurring pain points:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Coding feature retrieval logic for every new model was becoming unsustainable"}),"\n",(0,r.jsx)(n.li,{children:"ML scale was exploding\u2014bringing rising infra costs with it"}),"\n",(0,r.jsx)(n.li,{children:"Real-time embedding search was the next big unlock"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"We tackled them one by one\u2014starting with the biggest pain point."}),"\n",(0,r.jsx)(n.h4,{id:"problem-1-no-code-feature-retrieval-for-model-inference",children:"Problem 1: No-Code Feature Retrieval for Model Inference"}),"\n",(0,r.jsx)(n.p,{children:"We noticed a pattern: for personalized ranking, models needed features from:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\u2705 Product"}),"\n",(0,r.jsx)(n.li,{children:"\u2705 User"}),"\n",(0,r.jsx)(n.li,{children:"\u2705 User \xd7 Category"}),"\n",(0,r.jsx)(n.li,{children:"\u2705 Region, cohort, sub-category, etc."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"A key insight emerged: Entities that contribute features for a model always map back to the context entities."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"MP Dag",src:t(4114).A+"",width:"1272",height:"512"})}),"\n",(0,r.jsx)(n.p,{children:"With this, we designed Inferflow, a graph-driven feature retrieval and model orchestration system:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"1\ufe0f\u20e3 Inferflow takes a modelId and context IDs (e.g., userId, productIds)"}),"\n",(0,r.jsx)(n.li,{children:"2\ufe0f\u20e3 Loads a pre-defined feature retrieval graph from ZooKeeper"}),"\n",(0,r.jsx)(n.li,{children:"3\ufe0f\u20e3 Executes the graph to resolve entity relationships dynamically"}),"\n",(0,r.jsx)(n.li,{children:"4\ufe0f\u20e3 Outputs a 2D matrix of feature vectors"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"\ud83d\udca1 The impact?"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\ud83d\ude80 No more custom feature retrieval code\u2014just graph updates in config"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\ude80 Feature consistency across experiments"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\ude80 Faster iteration cycles for ranking, fraud detection, and beyond"}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Here\u2019s a visual example that shows how this graph plays out during execution. We further extended the graph to call multiple models as needed:\n",(0,r.jsx)(n.img,{alt:"MP matrix",src:t(8111).A+"",width:"1262",height:"768"}),"\nWe built Inferflow in GoLang, using gRPC and Proto3 serialization for efficiency."]}),"\n",(0,r.jsx)(n.h4,{id:"problem-2-scaling-without-breaking-the-bank",children:"Problem 2: Scaling Without Breaking the Bank"}),"\n",(0,r.jsx)(n.p,{children:"With more ML use cases coming online, we needed to cut costs without compromising performance. We focused on:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\ud83d\udd39 Online Feature Store"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\udd39 Interaction Store"}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"optimizing-the-online-feature-store",children:"Optimizing the Online Feature Store"}),"\n",(0,r.jsx)(n.p,{children:"Our costs were concentrated in:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\ud83d\udccc Database (Cassandra)"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\udccc Cache (Redis)"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\udccc Running Pods (Java services)"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"1\ufe0f\u20e3 Replacing Cassandra with ScyllaDB\nAs we hit the operational limits of large Cassandra clusters, we transitioned to ScyllaDB, which offered a seamless drop-in replacement without major code changes. The switch brought significant benefits:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Throughput: Matched or exceeded Cassandra's performance under identical workloads, even under high concurrency."}),"\n",(0,r.jsx)(n.li,{children:"Latency: Achieved consistently lower P99 latencies due to ScyllaDB's shard-per-core architecture and better I/O utilization."}),"\n",(0,r.jsx)(n.li,{children:"Cost Efficiency: Reduced infra footprint by ~70% through better CPU and memory efficiency, eliminating the need for over-provisioned nodes."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"2\ufe0f\u20e3 Finding the Right Cache\nTo reduce backend load and improve response times, we benchmarked multiple caching solutions\u2014Memcached, KeyDB, and Dragonfly\u2014under real production traffic patterns. Dragonfly stood out due to its robust architecture and operational simplicity:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Data Skew Handling: Efficiently managed extreme key hotness and uneven access patterns without performance degradation."}),"\n",(0,r.jsx)(n.li,{children:"Throughput: Delivered consistently high throughput, even with large object sizes and concurrent access."}),"\n",(0,r.jsx)(n.li,{children:"Ease of Adoption: Acted as a drop-in Redis replacement with full protocol compatibility\u2014no changes needed in application code or client libraries."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"3\ufe0f\u20e3 Moving to GoLang for Cost-Efficient Serving\nJava services were memory-heavy\u2014so we rewrote core services in GoLang. The results?"}),"\n",(0,r.jsx)(n.p,{children:"\u2705 Memory usage dropped by ~80%\n\u2705 CPU utilization was significantly lower\n\u2705 Faster, more efficient deployments"}),"\n",(0,r.jsx)(n.h4,{id:"optimizing-the-interaction-store",children:"Optimizing the Interaction Store"}),"\n",(0,r.jsx)(n.p,{children:"We realized that we only need a user\u2019s interaction data in Redis when they open the app. So, we implemented a tiered storage approach:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\ud83d\udccc Cold Tier (ScyllaDB)\u2014Stores click, order, wishlist events"}),"\n",(0,r.jsx)(n.li,{children:"\ud83d\udccc Hot Tier (Redis)\u2014Loads a user\u2019s past interactions only when they open the app"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Smart Offloading: We introduced an inactivity tracker to detect when a user session ends. At that point, Redis data was flushed back to Scylla, reducing unnecessary writes."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"InteractionStore",src:t(9758).A+"",width:"1242",height:"572"})}),"\n",(0,r.jsx)(n.h4,{id:"results",children:"Results"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Online Feature Store hit 1M QPS for the first time during the 2023 Mega Blockbuster Sale\u2014without breaking a sweat"}),"\n",(0,r.jsx)(n.li,{children:"Infra costs for Online Feature Store and Interaction Store dropped by ~60%"}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"the-catch-our-ml-hosting-hit-a-hard-limit",children:"The Catch: Our ML Hosting Hit a Hard Limit"}),"\n",(0,r.jsx)(n.p,{children:"While planning for 2023 MBS, we ran into a critical scalability bottleneck:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\u274c Insufficient compute availability in our region for ML instances"}),"\n",(0,r.jsx)(n.li,{children:"\u274c Couldn\u2019t provision enough nodes to handle real-time inference at scale"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"This forced us to rethink where and how we hosted our models. The existing setup was great for prototyping\u2014but it wasn\u2019t built to handle the bursty, high-QPS demands of real-world production workloads."}),"\n",(0,r.jsx)(n.h3,{id:"conclusion-from-firefighting-to-future-proofing",children:"Conclusion: From Firefighting to Future-Proofing"}),"\n",(0,r.jsx)(n.p,{children:"What started as an ambitious experiment turned into a real-time ML infrastructure that powered millions of requests per second. We battled scaling pains, rethought feature retrieval with Inferflow, and rebuilt our infra stack for efficiency\u2014driving down costs while improving experimentation velocity.\nBut new challenges emerged. Our infrastructure could now handle scale, but our ML model hosting setup hit a hard limit. With compute availability bottlenecks threatening real-time inference, we faced a critical decision: how do we make model serving as scalable and cost-efficient as the rest of our stack? That\u2019s the next piece of the puzzle\u2014and the story of Part 3."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8111:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/mp-matrix-43994f433f78905ccbd10cfe284f3c9f.png"},8453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var i=t(6540);const r={},s=i.createContext(r);function a(e){const n=i.useContext(s);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(s.Provider,{value:n},e.children)}},9758:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/interaction-str-d9e7aefea121aefb4e94c6c9f060d016.png"}}]); \ No newline at end of file diff --git a/docs/assets/js/aaabe254.ba3e9f5f.js b/docs/assets/js/aaabe254.ba3e9f5f.js new file mode 100644 index 00000000..40f78d18 --- /dev/null +++ b/docs/assets/js/aaabe254.ba3e9f5f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[770],{1982:a=>{a.exports=JSON.parse('{"tag":{"label":"bharatmlstack","permalink":"/BharatMLStack/blog/tags/bharatmlstack","allTagsPath":"/BharatMLStack/blog/tags","count":4,"unlisted":false},"listMetadata":{"permalink":"/BharatMLStack/blog/tags/bharatmlstack","page":1,"postsPerPage":10,"totalPages":1,"totalCount":4,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/ac51638e.cd23cca0.js b/docs/assets/js/ac51638e.cd23cca0.js deleted file mode 100644 index 524d3cba..00000000 --- a/docs/assets/js/ac51638e.cd23cca0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9473],{6692:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>p,frontMatter:()=>s,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"sdks/python/v1.0.0/spark_feature_push_client","title":"Spark client","description":"PyPI version","source":"@site/docs/sdks/python/v1.0.0/spark_feature_push_client.md","sourceDirName":"sdks/python/v1.0.0","slug":"/sdks/python/v1.0.0/spark_feature_push_client","permalink":"/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/sdks/python/v1.0.0/spark_feature_push_client.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"Spark client","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"GRPC Feature client","permalink":"/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client"}}');var r=a(4848),i=a(8453);const s={title:"Spark client",sidebar_position:1},o="Spark Feature Push Client",l={},c=[{value:"Installation",id:"installation",level:2},{value:"Dependencies",id:"dependencies",level:2},{value:"Architecture Role",id:"architecture-role",level:2},{value:"Features",id:"features",level:2},{value:"When to Use This Client",id:"when-to-use-this-client",level:2},{value:"Quick Start",id:"quick-start",level:2},{value:"Related Packages",id:"related-packages",level:2},{value:"License",id:"license",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Supported Data Sources",id:"supported-data-sources",level:2},{value:"1. Database Tables",id:"1-database-tables",level:3},{value:"2. Cloud Storage - Parquet",id:"2-cloud-storage---parquet",level:3},{value:"3. Cloud Storage - Delta",id:"3-cloud-storage---delta",level:3},{value:"Configuration Examples",id:"configuration-examples",level:2},{value:"Basic Pipeline",id:"basic-pipeline",level:3},{value:"Reading from Multiple Sources",id:"reading-from-multiple-sources",level:3},{value:"Protobuf Serialization & Kafka Publishing",id:"protobuf-serialization--kafka-publishing",level:3},{value:"Data Type Handling",id:"data-type-handling",level:2},{value:"Scalar Types",id:"scalar-types",level:3},{value:"Vector Types",id:"vector-types",level:3},{value:"Production Pipeline Example",id:"production-pipeline-example",level:2},{value:"Configuration Options",id:"configuration-options",level:2},{value:"Client Configuration",id:"client-configuration",level:3},{value:"Protobuf Serialization Options",id:"protobuf-serialization-options",level:3},{value:"Kafka Publishing Options",id:"kafka-publishing-options",level:3},{value:"Performance Tuning",id:"performance-tuning",level:2},{value:"Spark Optimizations",id:"spark-optimizations",level:3},{value:"Memory Management",id:"memory-management",level:3},{value:"Kafka Throughput",id:"kafka-throughput",level:3},{value:"Monitoring & Debugging",id:"monitoring--debugging",level:2},{value:"DataFrame Inspection",id:"dataframe-inspection",level:3},{value:"Error Handling",id:"error-handling",level:3},{value:"Integration with Other SDKs",id:"integration-with-other-sdks",level:2},{value:"With gRPC Feature Client",id:"with-grpc-feature-client",level:3},{value:"With HTTP Feature Client (bharatml_common)",id:"with-http-feature-client-bharatml_common",level:3},{value:"Common Use Cases",id:"common-use-cases",level:2},{value:"1. Daily Batch ETL",id:"1-daily-batch-etl",level:3},{value:"2. Historical Backfill",id:"2-historical-backfill",level:3},{value:"3. Real-time Streaming (Advanced)",id:"3-real-time-streaming-advanced",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Common Issues",id:"common-issues",level:3},{value:"Debug Mode",id:"debug-mode",level:3},{value:"Migration from Legacy Clients",id:"migration-from-legacy-clients",level:2},{value:"Best Practices",id:"best-practices",level:2},{value:"Contributing",id:"contributing-1",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license-1",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"spark-feature-push-client",children:"Spark Feature Push Client"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://badge.fury.io/py/spark_feature_push_client",children:(0,r.jsx)(n.img,{src:"https://img.shields.io/pypi/v/spark_feature_push_client?label=pypi-package&color=light%20green",alt:"PyPI version"})}),"\n",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/actions/workflows/py-sdk.yml",children:(0,r.jsx)(n.img,{src:"https://github.com/Meesho/BharatMLStack/actions/workflows/py-sdk.yml/badge.svg",alt:"Build Status"})}),"\n",(0,r.jsx)(n.a,{href:"https://www.python.org/downloads/",children:(0,r.jsx)(n.img,{src:"https://img.shields.io/badge/python-3.7+-blue.svg",alt:"Python 3.7+"})}),"\n",(0,r.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:(0,r.jsx)(n.img,{src:"https://img.shields.io/badge/Discord-Join%20Chat-7289da?style=flat&logo=discord&logoColor=white",alt:"Discord"})}),"\n",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:(0,r.jsx)(n.img,{src:"https://img.shields.io/badge/License-BharatMLStack%20BSL%201.1-blue.svg",alt:"License"})})]}),"\n",(0,r.jsxs)(n.p,{children:["Apache Spark-based client for pushing ML features from offline batch sources to the BharatML Stack Online Feature Store via Kafka. This client is designed for ",(0,r.jsx)(n.strong,{children:"data pipeline operations"})," - reading from batch sources and publishing to Kafka for online consumption."]}),"\n",(0,r.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"pip install spark_feature_push_client\n"})}),"\n",(0,r.jsx)(n.h2,{id:"dependencies",children:"Dependencies"}),"\n",(0,r.jsx)(n.p,{children:"This package depends on:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:(0,r.jsx)(n.a,{href:"https://pypi.org/project/bharatml_commons/",children:"bharatml_commons"})}),": Common utilities and protobuf definitions"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"PySpark 3.0+"}),": For distributed data processing"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"architecture-role",children:"Architecture Role"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Batch Sources \u2502\u2500\u2500\u2500\u25b6\u2502 Spark Feature Push \u2502\u2500\u2500\u2500\u25b6\u2502 Kafka \u2502\u2500\u2500\u2500\u25b6\u2502 Online Feature \u2502\n\u2502 \u2022 Tables \u2502 \u2502 Client \u2502 \u2502 \u2502 \u2502 Store \u2502\n\u2502 \u2022 Parquet \u2502 \u2502 \u2022 Read & Transform \u2502 \u2502 \u2502 \u2502 \u2502\n\u2502 \u2022 Delta \u2502 \u2502 \u2022 Protobuf Serialize \u2502 \u2502 \u2502 \u2502 \u2502\n\u2502 \u2022 S3/GCS/ADLS \u2502 \u2502 \u2022 Batch Processing \u2502 \u2502 \u2502 \u2502 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n \u25b2\n \u2502\n \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 grpc_feature_ \u2502\n \u2502 client \u2502\n \u2502 (Real-time) \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n"})}),"\n",(0,r.jsx)(n.h2,{id:"features",children:"Features"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Batch Source Integration"}),": Read from Tables (Hive/Delta), Parquet, and Delta files on cloud storage"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Spark Processing"}),": Leverage Apache Spark for distributed data processing"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Protobuf Serialization"}),": Convert feature data to protobuf format using bharatml_commons schemas"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Kafka Publishing"}),": Push serialized features to Kafka topics for online consumption"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Metadata Integration"}),": Fetch feature schemas and configurations via REST API"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Data Type Support"}),": Handle scalar and vector types (strings, numbers, booleans, arrays)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Batch Optimization"}),": Configurable batch sizes for optimal Kafka throughput"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"when-to-use-this-client",children:"When to Use This Client"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Use spark_feature_push_client for:"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\ud83d\udd04 ",(0,r.jsx)(n.strong,{children:"Batch ETL Pipelines"}),": Scheduled feature computation and publishing"]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udcca ",(0,r.jsx)(n.strong,{children:"Historical Data Backfill"}),": Loading historical features into online store"]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83c\udfd7\ufe0f ",(0,r.jsx)(n.strong,{children:"Data Engineering"}),": Spark-based feature transformations"]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udcc8 ",(0,r.jsx)(n.strong,{children:"Large Scale Processing"}),": Processing millions of records efficiently"]}),"\n",(0,r.jsxs)(n.li,{children:["\u26a1 ",(0,r.jsx)(n.strong,{children:"Offline-to-Online"}),": Bridge between batch and real-time systems"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Use grpc_feature_client for:"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\ud83d\ude80 ",(0,r.jsx)(n.strong,{children:"Real-time Operations"}),": Direct persist/retrieve operations"]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udd0d ",(0,r.jsx)(n.strong,{children:"Interactive Queries"}),": Low-latency feature lookups"]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83c\udfaf ",(0,r.jsx)(n.strong,{children:"API Integration"}),": Service-to-service communication"]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udca8 ",(0,r.jsx)(n.strong,{children:"Single Records"}),": Persisting individual feature records"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"quick-start",children:"Quick Start"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'from spark_feature_push_client import OnlineFeatureStorePyClient\n\n# Initialize client with metadata source\nclient = OnlineFeatureStorePyClient(\n features_metadata_source_url="https://api.example.com/metadata",\n job_id="feature-pipeline-job",\n job_token="your-auth-token"\n)\n\n# Get feature configuration \nfeature_details = client.get_features_details()\n\n# Process your Spark DataFrame\nproto_df = client.generate_df_with_protobuf_messages(your_spark_df)\n\n# Push to Kafka\nclient.write_protobuf_df_to_kafka(\n proto_df,\n kafka_bootstrap_servers="localhost:9092",\n kafka_topic="features.user_features"\n)\n'})}),"\n",(0,r.jsx)(n.h2,{id:"related-packages",children:"Related Packages"}),"\n",(0,r.jsx)(n.p,{children:"This package is part of the BharatML Stack ecosystem:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:(0,r.jsx)(n.a,{href:"https://pypi.org/project/bharatml_commons/",children:"bharatml_commons"})}),": Common utilities and protobuf definitions (required dependency)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:(0,r.jsx)(n.a,{href:"https://pypi.org/project/grpc_feature_client/",children:"grpc_feature_client"})}),": High-performance gRPC client for real-time operations"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,r.jsxs)(n.p,{children:["Licensed under the BharatMLStack Business Source License 1.1. See ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"LICENSE"})," for details."]}),"\n",(0,r.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,r.jsxs)(n.p,{children:["We welcome contributions! Please see our ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTION.md",children:"Contributing Guide"})," for details."]}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Apache Spark 3.0+"}),": For distributed processing"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Kafka Connector"}),": ",(0,r.jsx)(n.code,{children:"spark-sql-kafka"})," for Kafka integration"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Java 8/11"}),": Required by Spark"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"bharatml_common"}),": For protobuf schemas"]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'# Example Spark session setup\nspark = SparkSession.builder \\\n .appName("FeaturePipeline") \\\n .config("spark.jars.packages", "org.apache.spark:spark-sql-kafka-0-10_2.12:3.4.0") \\\n .getOrCreate()\n'})}),"\n",(0,r.jsx)(n.h2,{id:"supported-data-sources",children:"Supported Data Sources"}),"\n",(0,r.jsx)(n.h3,{id:"1-database-tables",children:"1. Database Tables"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Hive/Delta tables\ndf = spark.sql("SELECT * FROM feature_db.user_features")\n'})}),"\n",(0,r.jsx)(n.h3,{id:"2-cloud-storage---parquet",children:"2. Cloud Storage - Parquet"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# AWS S3\ndf = spark.read.parquet("s3a://bucket/path/to/features/")\n\n# Google Cloud Storage \ndf = spark.read.parquet("gs://bucket/path/to/features/")\n\n# Azure Data Lake\ndf = spark.read.parquet("abfss://container@account.dfs.core.windows.net/path/")\n'})}),"\n",(0,r.jsx)(n.h3,{id:"3-cloud-storage---delta",children:"3. Cloud Storage - Delta"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Delta format on cloud storage\ndf = spark.read.format("delta").load("s3a://bucket/delta-table/")\n'})}),"\n",(0,r.jsx)(n.h2,{id:"configuration-examples",children:"Configuration Examples"}),"\n",(0,r.jsx)(n.h3,{id:"basic-pipeline",children:"Basic Pipeline"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'from pyspark.sql import SparkSession\nfrom spark_feature_push_client import OnlineFeatureStorePyClient\n\n# Create Spark session\nspark = SparkSession.builder \\\n .appName("FeatureETL") \\\n .config("spark.jars.packages", "org.apache.spark:spark-sql-kafka-0-10_2.12:3.4.0") \\\n .getOrCreate()\n\n# Initialize client\nclient = OnlineFeatureStorePyClient(\n features_metadata_source_url="https://metadata-service.example.com/api/v1/features",\n job_id="daily-feature-pipeline",\n job_token="pipeline-secret-token",\n fgs_to_consider=["user_demographics", "user_behavior"] # Optional: filter feature groups\n)\n\n# Get metadata and column mappings\n(\n offline_src_type_columns,\n offline_col_to_default_values_map, \n entity_column_names\n) = client.get_features_details()\n\nprint(f"Entity columns: {entity_column_names}")\nprint(f"Feature mappings: {offline_src_type_columns}")\n'})}),"\n",(0,r.jsx)(n.h3,{id:"reading-from-multiple-sources",children:"Reading from Multiple Sources"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'def get_features_from_all_sources(spark, entity_columns, feature_mapping, default_values):\n """\n Read and combine features from multiple offline sources\n """\n dataframes = []\n \n for source_info in feature_mapping:\n table_name, source_type, feature_list = source_info\n \n if source_type == "TABLE":\n # Read from Hive/Delta table\n df = spark.table(table_name)\n \n elif source_type.startswith("PARQUET_"):\n # Read from Parquet files\n df = spark.read.parquet(table_name)\n \n elif source_type.startswith("DELTA_"):\n # Read from Delta files\n df = spark.read.format("delta").load(table_name)\n \n # Select and rename columns\n select_cols = entity_columns.copy()\n for original_col, renamed_col in feature_list:\n if original_col in df.columns:\n df = df.withColumnRenamed(original_col, renamed_col)\n select_cols.append(renamed_col)\n \n df = df.select(select_cols)\n dataframes.append(df)\n \n # Union all dataframes\n if dataframes:\n combined_df = dataframes[0]\n for df in dataframes[1:]:\n combined_df = combined_df.unionByName(df, allowMissingColumns=True)\n \n # Fill missing values with defaults\n for col, default_val in default_values.items():\n if col in combined_df.columns:\n combined_df = combined_df.fillna({col: default_val})\n \n return combined_df\n \n return None\n\n# Use the function\ndf = get_features_from_all_sources(\n spark, \n entity_column_names, \n offline_src_type_columns, \n offline_col_to_default_values_map\n)\n'})}),"\n",(0,r.jsx)(n.h3,{id:"protobuf-serialization--kafka-publishing",children:"Protobuf Serialization & Kafka Publishing"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Convert DataFrame to protobuf messages\n# This creates binary protobuf messages suitable for Kafka\nproto_df = client.generate_df_with_protobuf_messages(\n df, \n intra_batch_size=20 # Batch size for serialization\n)\n\n# The proto_df has schema: [value: binary, intra_batch_id: long]\nproto_df.printSchema()\n# root\n# |-- value: binary (nullable = false) \n# |-- intra_batch_id: long (nullable = false)\n\n# Write to Kafka with batching for better throughput\nclient.write_protobuf_df_to_kafka(\n proto_df,\n kafka_bootstrap_servers="broker1:9092,broker2:9092,broker3:9092",\n kafka_topic="features.user_features",\n additional_options={\n "kafka.acks": "all",\n "kafka.retries": "3",\n "kafka.compression.type": "snappy"\n },\n kafka_num_batches=4 # Split into 4 parallel Kafka writes\n)\n'})}),"\n",(0,r.jsx)(n.h2,{id:"data-type-handling",children:"Data Type Handling"}),"\n",(0,r.jsx)(n.p,{children:"The client automatically handles the protobuf data type mappings:"}),"\n",(0,r.jsx)(n.h3,{id:"scalar-types",children:"Scalar Types"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Example DataFrame with different types\ndata = [\n ("user123", 25, 185.5, True, "premium"), # int, float, bool, string\n ("user456", 30, 170.0, False, "basic")\n]\ndf = spark.createDataFrame(data, ["user_id", "age", "height", "is_premium", "tier"])\n\n# Automatically mapped to protobuf:\n# age -> int32_values\n# height -> fp32_values \n# is_premium -> bool_values\n# tier -> string_values\n'})}),"\n",(0,r.jsx)(n.h3,{id:"vector-types",children:"Vector Types"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Example with vector/array features\nfrom pyspark.sql.functions import array, lit\n\ndf = spark.createDataFrame([\n ("user123", [0.1, 0.2, 0.3], ["tech", "sports"], [1, 2, 3])\n], ["user_id", "embeddings", "interests", "scores"])\n\n# Automatically mapped to protobuf vectors:\n# embeddings -> fp32_values in Vector\n# interests -> string_values in Vector\n# scores -> int32_values in Vector\n'})}),"\n",(0,r.jsx)(n.h2,{id:"production-pipeline-example",children:"Production Pipeline Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'def run_feature_pipeline():\n """\n Complete feature pipeline from batch sources to Kafka\n """\n \n # 1. Initialize Spark\n spark = SparkSession.builder \\\n .appName("DailyFeaturePipeline") \\\n .config("spark.sql.adaptive.enabled", "true") \\\n .config("spark.jars.packages", "org.apache.spark:spark-sql-kafka-0-10_2.12:3.4.0") \\\n .getOrCreate()\n \n try:\n # 2. Initialize feature client\n client = OnlineFeatureStorePyClient(\n features_metadata_source_url=os.getenv("METADATA_URL"),\n job_id=os.getenv("JOB_ID"),\n job_token=os.getenv("JOB_TOKEN")\n )\n \n # 3. Get feature configuration\n feature_mapping, default_values, entity_columns = client.get_features_details()\n \n # 4. Read and process data\n df = get_features_from_all_sources(spark, entity_columns, feature_mapping, default_values)\n \n if df is None or df.count() == 0:\n raise ValueError("No data found in sources")\n \n # 5. Convert to protobuf\n proto_df = client.generate_df_with_protobuf_messages(df, intra_batch_size=50)\n \n # 6. Publish to Kafka\n client.write_protobuf_df_to_kafka(\n proto_df,\n kafka_bootstrap_servers=os.getenv("KAFKA_BROKERS"),\n kafka_topic=os.getenv("KAFKA_TOPIC"),\n additional_options={\n "kafka.acks": "all",\n "kafka.compression.type": "snappy",\n "kafka.max.request.size": "10485760" # 10MB\n },\n kafka_num_batches=int(os.getenv("KAFKA_BATCHES", "4"))\n )\n \n print(f"\u2705 Successfully processed {df.count()} records")\n \n finally:\n spark.stop()\n\nif __name__ == "__main__":\n run_feature_pipeline()\n'})}),"\n",(0,r.jsx)(n.h2,{id:"configuration-options",children:"Configuration Options"}),"\n",(0,r.jsx)(n.h3,{id:"client-configuration",children:"Client Configuration"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'client = OnlineFeatureStorePyClient(\n features_metadata_source_url="https://api.example.com/metadata", # Required\n job_id="pipeline-job-001", # Required \n job_token="secret-token-123", # Required\n fgs_to_consider=["user_features", "item_features"] # Optional: filter feature groups\n)\n'})}),"\n",(0,r.jsx)(n.h3,{id:"protobuf-serialization-options",children:"Protobuf Serialization Options"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:"proto_df = client.generate_df_with_protobuf_messages(\n df,\n intra_batch_size=20 # Records per protobuf message (default: 20)\n)\n"})}),"\n",(0,r.jsx)(n.h3,{id:"kafka-publishing-options",children:"Kafka Publishing Options"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'client.write_protobuf_df_to_kafka(\n proto_df,\n kafka_bootstrap_servers="localhost:9092",\n kafka_topic="features.topic",\n additional_options={\n "kafka.acks": "all", # Acknowledgment level\n "kafka.retries": "3", # Retry attempts\n "kafka.compression.type": "snappy", # Compression\n "kafka.batch.size": "16384", # Batch size\n "kafka.linger.ms": "100", # Batching delay\n "kafka.max.request.size": "10485760" # Max message size\n },\n kafka_num_batches=1 # Number of parallel Kafka writers (default: 1)\n)\n'})}),"\n",(0,r.jsx)(n.h2,{id:"performance-tuning",children:"Performance Tuning"}),"\n",(0,r.jsx)(n.h3,{id:"spark-optimizations",children:"Spark Optimizations"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'spark = SparkSession.builder \\\n .appName("FeaturePipeline") \\\n .config("spark.sql.adaptive.enabled", "true") \\\n .config("spark.sql.adaptive.coalescePartitions.enabled", "true") \\\n .config("spark.sql.adaptive.skewJoin.enabled", "true") \\\n .config("spark.serializer", "org.apache.spark.serializer.KryoSerializer") \\\n .getOrCreate()\n'})}),"\n",(0,r.jsx)(n.h3,{id:"memory-management",children:"Memory Management"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:"# For large datasets, consider:\ndf = df.repartition(200) # Optimal partition count\ndf.cache() # Cache if reused multiple times\n"})}),"\n",(0,r.jsx)(n.h3,{id:"kafka-throughput",children:"Kafka Throughput"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# For high-throughput scenarios:\nclient.write_protobuf_df_to_kafka(\n proto_df,\n kafka_bootstrap_servers="brokers",\n kafka_topic="topic", \n kafka_num_batches=8, # Increase parallel writers\n additional_options={\n "kafka.batch.size": "65536", # Larger batches\n "kafka.linger.ms": "100", # Allow batching delay\n "kafka.compression.type": "lz4" # Fast compression\n }\n)\n'})}),"\n",(0,r.jsx)(n.h2,{id:"monitoring--debugging",children:"Monitoring & Debugging"}),"\n",(0,r.jsx)(n.h3,{id:"dataframe-inspection",children:"DataFrame Inspection"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Check data before processing\nprint(f"Records: {df.count()}")\nprint(f"Columns: {df.columns}")\ndf.printSchema()\ndf.show(5)\n\n# Check protobuf output\nproto_df.show(5, truncate=False)\nprint(f"Protobuf messages: {proto_df.count()}")\n'})}),"\n",(0,r.jsx)(n.h3,{id:"error-handling",children:"Error Handling"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'try:\n proto_df = client.generate_df_with_protobuf_messages(df)\n client.write_protobuf_df_to_kafka(proto_df, brokers, topic)\n \nexcept Exception as e:\n print(f"Pipeline failed: {e}")\n # Log to monitoring system\n # Send alerts\n raise\n'})}),"\n",(0,r.jsx)(n.h2,{id:"integration-with-other-sdks",children:"Integration with Other SDKs"}),"\n",(0,r.jsx)(n.h3,{id:"with-grpc-feature-client",children:"With gRPC Feature Client"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:"# Spark client pushes features to Kafka\nspark_client = OnlineFeatureStorePyClient(...)\nspark_client.write_protobuf_df_to_kafka(proto_df, brokers, topic)\n\n# gRPC client retrieves features in real-time\nfrom grpc_feature_client import GRPCFeatureClient\ngrpc_client = GRPCFeatureClient(config)\nfeatures = grpc_client.retrieve_decoded_features(...)\n"})}),"\n",(0,r.jsx)(n.h3,{id:"with-http-feature-client-bharatml_common",children:"With HTTP Feature Client (bharatml_common)"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:"# Use HTTP client for metadata validation\nfrom bharatml_common import HTTPFeatureClient\nhttp_client = HTTPFeatureClient(base_url, job_id, token)\nmetadata = http_client.get_feature_metadata()\n\n# Validate feature names using shared utilities\nfrom bharatml_common import clean_column_name\nclean_features = [clean_column_name(name) for name in feature_names]\n\n# Process with Spark client\nspark_client.generate_df_with_protobuf_messages(df)\n"})}),"\n",(0,r.jsx)(n.h2,{id:"common-use-cases",children:"Common Use Cases"}),"\n",(0,r.jsx)(n.h3,{id:"1-daily-batch-etl",children:"1. Daily Batch ETL"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# Cron job: 0 2 * * * (daily at 2 AM)\nspark-submit \\\n --packages org.apache.spark:spark-sql-kafka-0-10_2.12:3.4.0 \\\n --conf spark.sql.adaptive.enabled=true \\\n daily_feature_pipeline.py\n"})}),"\n",(0,r.jsx)(n.h3,{id:"2-historical-backfill",children:"2. Historical Backfill"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Backfill last 30 days\nfrom datetime import datetime, timedelta\n\nfor i in range(30):\n date = datetime.now() - timedelta(days=i)\n df = spark.sql(f"""\n SELECT * FROM features \n WHERE date = \'{date.strftime(\'%Y-%m-%d\')}\'\n """)\n \n proto_df = client.generate_df_with_protobuf_messages(df)\n client.write_protobuf_df_to_kafka(proto_df, brokers, f"backfill.{date.strftime(\'%Y%m%d\')}")\n'})}),"\n",(0,r.jsx)(n.h3,{id:"3-real-time-streaming-advanced",children:"3. Real-time Streaming (Advanced)"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Read from streaming source, process, and publish\nstreaming_df = spark.readStream \\\n .format("kafka") \\\n .option("kafka.bootstrap.servers", input_brokers) \\\n .option("subscribe", input_topic) \\\n .load()\n\n# Process streaming DataFrame\nprocessed_df = streaming_df.select(...)\n\n# Write to output Kafka (requires structured streaming)\nquery = processed_df.writeStream \\\n .format("kafka") \\\n .option("kafka.bootstrap.servers", output_brokers) \\\n .option("topic", output_topic) \\\n .start()\n'})}),"\n",(0,r.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,r.jsx)(n.h3,{id:"common-issues",children:"Common Issues"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"OutOfMemoryError"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Increase driver memory or reduce partition size\nspark.conf.set("spark.sql.adaptive.coalescePartitions.minPartitionNum", "50")\n'})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Kafka Connection Timeout"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Check network connectivity and broker addresses\nadditional_options = {\n "kafka.request.timeout.ms": "60000",\n "kafka.session.timeout.ms": "30000"\n}\n'})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Protobuf Serialization Errors"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Check data types and null values\ndf = df.fillna({"string_col": "", "numeric_col": 0})\n'})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Metadata API Errors"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:"# Verify job_id, job_token, and URL\n# Check API server logs\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"debug-mode",children:"Debug Mode"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'import logging\nlogging.basicConfig(level=logging.DEBUG)\n\n# Enable Spark SQL logging\nspark.sparkContext.setLogLevel("INFO")\n'})}),"\n",(0,r.jsx)(n.h2,{id:"migration-from-legacy-clients",children:"Migration from Legacy Clients"}),"\n",(0,r.jsx)(n.p,{children:"If migrating from older versions:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:"# Old import\n# from online_feature_store_py_client import OnlineFeatureStorePyClient\n\n# New import (same interface)\nfrom spark_feature_push_client import OnlineFeatureStorePyClient\n\n# API remains the same - no code changes needed!\n"})}),"\n",(0,r.jsx)(n.h2,{id:"best-practices",children:"Best Practices"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Resource Management"}),": Always stop Spark sessions"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Error Handling"}),": Implement proper exception handling and retries"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Monitoring"}),": Add metrics and logging to your pipelines"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Testing"}),": Test with sample data before production runs"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Security"}),": Use secure Kafka configurations in production"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Performance"}),": Monitor Spark UI for optimization opportunities"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The Spark Feature Push Client is your gateway from batch data sources to the real-time online feature store! \ud83d\ude80"}),"\n",(0,r.jsx)(n.h2,{id:"contributing-1",children:"Contributing"}),"\n",(0,r.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,r.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\ud83d\udcac ",(0,r.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,r.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,r.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,r.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,r.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"license-1",children:"License"}),"\n",(0,r.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)("div",{align:"center",children:(0,r.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,r.jsx)("div",{align:"center",children:(0,r.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function p(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>o});var t=a(6540);const r={},i=t.createContext(r);function s(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/ac51638e.ef64a004.js b/docs/assets/js/ac51638e.ef64a004.js new file mode 100644 index 00000000..d229d3ec --- /dev/null +++ b/docs/assets/js/ac51638e.ef64a004.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9473],{6692:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"sdks/python/v1.0.0/spark_feature_push_client","title":"Spark client","description":"PyPI version","source":"@site/docs/sdks/python/v1.0.0/spark_feature_push_client.md","sourceDirName":"sdks/python/v1.0.0","slug":"/sdks/python/v1.0.0/spark_feature_push_client","permalink":"/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/sdks/python/v1.0.0/spark_feature_push_client.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"Spark client","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"GRPC Feature client","permalink":"/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client"},"next":{"title":"Numerix","permalink":"/BharatMLStack/category/numerix"}}');var r=a(4848),i=a(8453);const s={title:"Spark client",sidebar_position:1},o="Spark Feature Push Client",l={},c=[{value:"Installation",id:"installation",level:2},{value:"Dependencies",id:"dependencies",level:2},{value:"Architecture Role",id:"architecture-role",level:2},{value:"Features",id:"features",level:2},{value:"When to Use This Client",id:"when-to-use-this-client",level:2},{value:"Quick Start",id:"quick-start",level:2},{value:"Related Packages",id:"related-packages",level:2},{value:"License",id:"license",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Supported Data Sources",id:"supported-data-sources",level:2},{value:"1. Database Tables",id:"1-database-tables",level:3},{value:"2. Cloud Storage - Parquet",id:"2-cloud-storage---parquet",level:3},{value:"3. Cloud Storage - Delta",id:"3-cloud-storage---delta",level:3},{value:"Configuration Examples",id:"configuration-examples",level:2},{value:"Basic Pipeline",id:"basic-pipeline",level:3},{value:"Reading from Multiple Sources",id:"reading-from-multiple-sources",level:3},{value:"Protobuf Serialization & Kafka Publishing",id:"protobuf-serialization--kafka-publishing",level:3},{value:"Data Type Handling",id:"data-type-handling",level:2},{value:"Scalar Types",id:"scalar-types",level:3},{value:"Vector Types",id:"vector-types",level:3},{value:"Production Pipeline Example",id:"production-pipeline-example",level:2},{value:"Configuration Options",id:"configuration-options",level:2},{value:"Client Configuration",id:"client-configuration",level:3},{value:"Protobuf Serialization Options",id:"protobuf-serialization-options",level:3},{value:"Kafka Publishing Options",id:"kafka-publishing-options",level:3},{value:"Performance Tuning",id:"performance-tuning",level:2},{value:"Spark Optimizations",id:"spark-optimizations",level:3},{value:"Memory Management",id:"memory-management",level:3},{value:"Kafka Throughput",id:"kafka-throughput",level:3},{value:"Monitoring & Debugging",id:"monitoring--debugging",level:2},{value:"DataFrame Inspection",id:"dataframe-inspection",level:3},{value:"Error Handling",id:"error-handling",level:3},{value:"Integration with Other SDKs",id:"integration-with-other-sdks",level:2},{value:"With gRPC Feature Client",id:"with-grpc-feature-client",level:3},{value:"With HTTP Feature Client (bharatml_common)",id:"with-http-feature-client-bharatml_common",level:3},{value:"Common Use Cases",id:"common-use-cases",level:2},{value:"1. Daily Batch ETL",id:"1-daily-batch-etl",level:3},{value:"2. Historical Backfill",id:"2-historical-backfill",level:3},{value:"3. Real-time Streaming (Advanced)",id:"3-real-time-streaming-advanced",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Common Issues",id:"common-issues",level:3},{value:"Debug Mode",id:"debug-mode",level:3},{value:"Migration from Legacy Clients",id:"migration-from-legacy-clients",level:2},{value:"Best Practices",id:"best-practices",level:2},{value:"Contributing",id:"contributing-1",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license-1",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"spark-feature-push-client",children:"Spark Feature Push Client"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://badge.fury.io/py/spark_feature_push_client",children:(0,r.jsx)(n.img,{src:"https://img.shields.io/pypi/v/spark_feature_push_client?label=pypi-package&color=light%20green",alt:"PyPI version"})}),"\n",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/actions/workflows/py-sdk.yml",children:(0,r.jsx)(n.img,{src:"https://github.com/Meesho/BharatMLStack/actions/workflows/py-sdk.yml/badge.svg",alt:"Build Status"})}),"\n",(0,r.jsx)(n.a,{href:"https://www.python.org/downloads/",children:(0,r.jsx)(n.img,{src:"https://img.shields.io/badge/python-3.7+-blue.svg",alt:"Python 3.7+"})}),"\n",(0,r.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:(0,r.jsx)(n.img,{src:"https://img.shields.io/badge/Discord-Join%20Chat-7289da?style=flat&logo=discord&logoColor=white",alt:"Discord"})}),"\n",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:(0,r.jsx)(n.img,{src:"https://img.shields.io/badge/License-BharatMLStack%20BSL%201.1-blue.svg",alt:"License"})})]}),"\n",(0,r.jsxs)(n.p,{children:["Apache Spark-based client for pushing ML features from offline batch sources to the BharatML Stack Online Feature Store via Kafka. This client is designed for ",(0,r.jsx)(n.strong,{children:"data pipeline operations"})," - reading from batch sources and publishing to Kafka for online consumption."]}),"\n",(0,r.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"pip install spark_feature_push_client\n"})}),"\n",(0,r.jsx)(n.h2,{id:"dependencies",children:"Dependencies"}),"\n",(0,r.jsx)(n.p,{children:"This package depends on:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:(0,r.jsx)(n.a,{href:"https://pypi.org/project/bharatml_commons/",children:"bharatml_commons"})}),": Common utilities and protobuf definitions"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"PySpark 3.0+"}),": For distributed data processing"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"architecture-role",children:"Architecture Role"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Batch Sources \u2502\u2500\u2500\u2500\u25b6\u2502 Spark Feature Push \u2502\u2500\u2500\u2500\u25b6\u2502 Kafka \u2502\u2500\u2500\u2500\u25b6\u2502 Online Feature \u2502\n\u2502 \u2022 Tables \u2502 \u2502 Client \u2502 \u2502 \u2502 \u2502 Store \u2502\n\u2502 \u2022 Parquet \u2502 \u2502 \u2022 Read & Transform \u2502 \u2502 \u2502 \u2502 \u2502\n\u2502 \u2022 Delta \u2502 \u2502 \u2022 Protobuf Serialize \u2502 \u2502 \u2502 \u2502 \u2502\n\u2502 \u2022 S3/GCS/ADLS \u2502 \u2502 \u2022 Batch Processing \u2502 \u2502 \u2502 \u2502 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n \u25b2\n \u2502\n \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 grpc_feature_ \u2502\n \u2502 client \u2502\n \u2502 (Real-time) \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n"})}),"\n",(0,r.jsx)(n.h2,{id:"features",children:"Features"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Batch Source Integration"}),": Read from Tables (Hive/Delta), Parquet, and Delta files on cloud storage"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Spark Processing"}),": Leverage Apache Spark for distributed data processing"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Protobuf Serialization"}),": Convert feature data to protobuf format using bharatml_commons schemas"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Kafka Publishing"}),": Push serialized features to Kafka topics for online consumption"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Metadata Integration"}),": Fetch feature schemas and configurations via REST API"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Data Type Support"}),": Handle scalar and vector types (strings, numbers, booleans, arrays)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Batch Optimization"}),": Configurable batch sizes for optimal Kafka throughput"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"when-to-use-this-client",children:"When to Use This Client"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Use spark_feature_push_client for:"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\ud83d\udd04 ",(0,r.jsx)(n.strong,{children:"Batch ETL Pipelines"}),": Scheduled feature computation and publishing"]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udcca ",(0,r.jsx)(n.strong,{children:"Historical Data Backfill"}),": Loading historical features into online store"]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83c\udfd7\ufe0f ",(0,r.jsx)(n.strong,{children:"Data Engineering"}),": Spark-based feature transformations"]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udcc8 ",(0,r.jsx)(n.strong,{children:"Large Scale Processing"}),": Processing millions of records efficiently"]}),"\n",(0,r.jsxs)(n.li,{children:["\u26a1 ",(0,r.jsx)(n.strong,{children:"Offline-to-Online"}),": Bridge between batch and real-time systems"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Use grpc_feature_client for:"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\ud83d\ude80 ",(0,r.jsx)(n.strong,{children:"Real-time Operations"}),": Direct persist/retrieve operations"]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udd0d ",(0,r.jsx)(n.strong,{children:"Interactive Queries"}),": Low-latency feature lookups"]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83c\udfaf ",(0,r.jsx)(n.strong,{children:"API Integration"}),": Service-to-service communication"]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udca8 ",(0,r.jsx)(n.strong,{children:"Single Records"}),": Persisting individual feature records"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"quick-start",children:"Quick Start"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'from spark_feature_push_client import OnlineFeatureStorePyClient\n\n# Initialize client with metadata source\nclient = OnlineFeatureStorePyClient(\n features_metadata_source_url="https://api.example.com/metadata",\n job_id="feature-pipeline-job",\n job_token="your-auth-token"\n)\n\n# Get feature configuration \nfeature_details = client.get_features_details()\n\n# Process your Spark DataFrame\nproto_df = client.generate_df_with_protobuf_messages(your_spark_df)\n\n# Push to Kafka\nclient.write_protobuf_df_to_kafka(\n proto_df,\n kafka_bootstrap_servers="localhost:9092",\n kafka_topic="features.user_features"\n)\n'})}),"\n",(0,r.jsx)(n.h2,{id:"related-packages",children:"Related Packages"}),"\n",(0,r.jsx)(n.p,{children:"This package is part of the BharatML Stack ecosystem:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:(0,r.jsx)(n.a,{href:"https://pypi.org/project/bharatml_commons/",children:"bharatml_commons"})}),": Common utilities and protobuf definitions (required dependency)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:(0,r.jsx)(n.a,{href:"https://pypi.org/project/grpc_feature_client/",children:"grpc_feature_client"})}),": High-performance gRPC client for real-time operations"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,r.jsxs)(n.p,{children:["Licensed under the BharatMLStack Business Source License 1.1. See ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"LICENSE"})," for details."]}),"\n",(0,r.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,r.jsxs)(n.p,{children:["We welcome contributions! Please see our ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTION.md",children:"Contributing Guide"})," for details."]}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Apache Spark 3.0+"}),": For distributed processing"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Kafka Connector"}),": ",(0,r.jsx)(n.code,{children:"spark-sql-kafka"})," for Kafka integration"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Java 8/11"}),": Required by Spark"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"bharatml_common"}),": For protobuf schemas"]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'# Example Spark session setup\nspark = SparkSession.builder \\\n .appName("FeaturePipeline") \\\n .config("spark.jars.packages", "org.apache.spark:spark-sql-kafka-0-10_2.12:3.4.0") \\\n .getOrCreate()\n'})}),"\n",(0,r.jsx)(n.h2,{id:"supported-data-sources",children:"Supported Data Sources"}),"\n",(0,r.jsx)(n.h3,{id:"1-database-tables",children:"1. Database Tables"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Hive/Delta tables\ndf = spark.sql("SELECT * FROM feature_db.user_features")\n'})}),"\n",(0,r.jsx)(n.h3,{id:"2-cloud-storage---parquet",children:"2. Cloud Storage - Parquet"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# AWS S3\ndf = spark.read.parquet("s3a://bucket/path/to/features/")\n\n# Google Cloud Storage \ndf = spark.read.parquet("gs://bucket/path/to/features/")\n\n# Azure Data Lake\ndf = spark.read.parquet("abfss://container@account.dfs.core.windows.net/path/")\n'})}),"\n",(0,r.jsx)(n.h3,{id:"3-cloud-storage---delta",children:"3. Cloud Storage - Delta"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Delta format on cloud storage\ndf = spark.read.format("delta").load("s3a://bucket/delta-table/")\n'})}),"\n",(0,r.jsx)(n.h2,{id:"configuration-examples",children:"Configuration Examples"}),"\n",(0,r.jsx)(n.h3,{id:"basic-pipeline",children:"Basic Pipeline"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'from pyspark.sql import SparkSession\nfrom spark_feature_push_client import OnlineFeatureStorePyClient\n\n# Create Spark session\nspark = SparkSession.builder \\\n .appName("FeatureETL") \\\n .config("spark.jars.packages", "org.apache.spark:spark-sql-kafka-0-10_2.12:3.4.0") \\\n .getOrCreate()\n\n# Initialize client\nclient = OnlineFeatureStorePyClient(\n features_metadata_source_url="https://metadata-service.example.com/api/v1/features",\n job_id="daily-feature-pipeline",\n job_token="pipeline-secret-token",\n fgs_to_consider=["user_demographics", "user_behavior"] # Optional: filter feature groups\n)\n\n# Get metadata and column mappings\n(\n offline_src_type_columns,\n offline_col_to_default_values_map, \n entity_column_names\n) = client.get_features_details()\n\nprint(f"Entity columns: {entity_column_names}")\nprint(f"Feature mappings: {offline_src_type_columns}")\n'})}),"\n",(0,r.jsx)(n.h3,{id:"reading-from-multiple-sources",children:"Reading from Multiple Sources"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'def get_features_from_all_sources(spark, entity_columns, feature_mapping, default_values):\n """\n Read and combine features from multiple offline sources\n """\n dataframes = []\n \n for source_info in feature_mapping:\n table_name, source_type, feature_list = source_info\n \n if source_type == "TABLE":\n # Read from Hive/Delta table\n df = spark.table(table_name)\n \n elif source_type.startswith("PARQUET_"):\n # Read from Parquet files\n df = spark.read.parquet(table_name)\n \n elif source_type.startswith("DELTA_"):\n # Read from Delta files\n df = spark.read.format("delta").load(table_name)\n \n # Select and rename columns\n select_cols = entity_columns.copy()\n for original_col, renamed_col in feature_list:\n if original_col in df.columns:\n df = df.withColumnRenamed(original_col, renamed_col)\n select_cols.append(renamed_col)\n \n df = df.select(select_cols)\n dataframes.append(df)\n \n # Union all dataframes\n if dataframes:\n combined_df = dataframes[0]\n for df in dataframes[1:]:\n combined_df = combined_df.unionByName(df, allowMissingColumns=True)\n \n # Fill missing values with defaults\n for col, default_val in default_values.items():\n if col in combined_df.columns:\n combined_df = combined_df.fillna({col: default_val})\n \n return combined_df\n \n return None\n\n# Use the function\ndf = get_features_from_all_sources(\n spark, \n entity_column_names, \n offline_src_type_columns, \n offline_col_to_default_values_map\n)\n'})}),"\n",(0,r.jsx)(n.h3,{id:"protobuf-serialization--kafka-publishing",children:"Protobuf Serialization & Kafka Publishing"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Convert DataFrame to protobuf messages\n# This creates binary protobuf messages suitable for Kafka\nproto_df = client.generate_df_with_protobuf_messages(\n df, \n intra_batch_size=20 # Batch size for serialization\n)\n\n# The proto_df has schema: [value: binary, intra_batch_id: long]\nproto_df.printSchema()\n# root\n# |-- value: binary (nullable = false) \n# |-- intra_batch_id: long (nullable = false)\n\n# Write to Kafka with batching for better throughput\nclient.write_protobuf_df_to_kafka(\n proto_df,\n kafka_bootstrap_servers="broker1:9092,broker2:9092,broker3:9092",\n kafka_topic="features.user_features",\n additional_options={\n "kafka.acks": "all",\n "kafka.retries": "3",\n "kafka.compression.type": "snappy"\n },\n kafka_num_batches=4 # Split into 4 parallel Kafka writes\n)\n'})}),"\n",(0,r.jsx)(n.h2,{id:"data-type-handling",children:"Data Type Handling"}),"\n",(0,r.jsx)(n.p,{children:"The client automatically handles the protobuf data type mappings:"}),"\n",(0,r.jsx)(n.h3,{id:"scalar-types",children:"Scalar Types"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Example DataFrame with different types\ndata = [\n ("user123", 25, 185.5, True, "premium"), # int, float, bool, string\n ("user456", 30, 170.0, False, "basic")\n]\ndf = spark.createDataFrame(data, ["user_id", "age", "height", "is_premium", "tier"])\n\n# Automatically mapped to protobuf:\n# age -> int32_values\n# height -> fp32_values \n# is_premium -> bool_values\n# tier -> string_values\n'})}),"\n",(0,r.jsx)(n.h3,{id:"vector-types",children:"Vector Types"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Example with vector/array features\nfrom pyspark.sql.functions import array, lit\n\ndf = spark.createDataFrame([\n ("user123", [0.1, 0.2, 0.3], ["tech", "sports"], [1, 2, 3])\n], ["user_id", "embeddings", "interests", "scores"])\n\n# Automatically mapped to protobuf vectors:\n# embeddings -> fp32_values in Vector\n# interests -> string_values in Vector\n# scores -> int32_values in Vector\n'})}),"\n",(0,r.jsx)(n.h2,{id:"production-pipeline-example",children:"Production Pipeline Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'def run_feature_pipeline():\n """\n Complete feature pipeline from batch sources to Kafka\n """\n \n # 1. Initialize Spark\n spark = SparkSession.builder \\\n .appName("DailyFeaturePipeline") \\\n .config("spark.sql.adaptive.enabled", "true") \\\n .config("spark.jars.packages", "org.apache.spark:spark-sql-kafka-0-10_2.12:3.4.0") \\\n .getOrCreate()\n \n try:\n # 2. Initialize feature client\n client = OnlineFeatureStorePyClient(\n features_metadata_source_url=os.getenv("METADATA_URL"),\n job_id=os.getenv("JOB_ID"),\n job_token=os.getenv("JOB_TOKEN")\n )\n \n # 3. Get feature configuration\n feature_mapping, default_values, entity_columns = client.get_features_details()\n \n # 4. Read and process data\n df = get_features_from_all_sources(spark, entity_columns, feature_mapping, default_values)\n \n if df is None or df.count() == 0:\n raise ValueError("No data found in sources")\n \n # 5. Convert to protobuf\n proto_df = client.generate_df_with_protobuf_messages(df, intra_batch_size=50)\n \n # 6. Publish to Kafka\n client.write_protobuf_df_to_kafka(\n proto_df,\n kafka_bootstrap_servers=os.getenv("KAFKA_BROKERS"),\n kafka_topic=os.getenv("KAFKA_TOPIC"),\n additional_options={\n "kafka.acks": "all",\n "kafka.compression.type": "snappy",\n "kafka.max.request.size": "10485760" # 10MB\n },\n kafka_num_batches=int(os.getenv("KAFKA_BATCHES", "4"))\n )\n \n print(f"\u2705 Successfully processed {df.count()} records")\n \n finally:\n spark.stop()\n\nif __name__ == "__main__":\n run_feature_pipeline()\n'})}),"\n",(0,r.jsx)(n.h2,{id:"configuration-options",children:"Configuration Options"}),"\n",(0,r.jsx)(n.h3,{id:"client-configuration",children:"Client Configuration"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'client = OnlineFeatureStorePyClient(\n features_metadata_source_url="https://api.example.com/metadata", # Required\n job_id="pipeline-job-001", # Required \n job_token="secret-token-123", # Required\n fgs_to_consider=["user_features", "item_features"] # Optional: filter feature groups\n)\n'})}),"\n",(0,r.jsx)(n.h3,{id:"protobuf-serialization-options",children:"Protobuf Serialization Options"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:"proto_df = client.generate_df_with_protobuf_messages(\n df,\n intra_batch_size=20 # Records per protobuf message (default: 20)\n)\n"})}),"\n",(0,r.jsx)(n.h3,{id:"kafka-publishing-options",children:"Kafka Publishing Options"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'client.write_protobuf_df_to_kafka(\n proto_df,\n kafka_bootstrap_servers="localhost:9092",\n kafka_topic="features.topic",\n additional_options={\n "kafka.acks": "all", # Acknowledgment level\n "kafka.retries": "3", # Retry attempts\n "kafka.compression.type": "snappy", # Compression\n "kafka.batch.size": "16384", # Batch size\n "kafka.linger.ms": "100", # Batching delay\n "kafka.max.request.size": "10485760" # Max message size\n },\n kafka_num_batches=1 # Number of parallel Kafka writers (default: 1)\n)\n'})}),"\n",(0,r.jsx)(n.h2,{id:"performance-tuning",children:"Performance Tuning"}),"\n",(0,r.jsx)(n.h3,{id:"spark-optimizations",children:"Spark Optimizations"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'spark = SparkSession.builder \\\n .appName("FeaturePipeline") \\\n .config("spark.sql.adaptive.enabled", "true") \\\n .config("spark.sql.adaptive.coalescePartitions.enabled", "true") \\\n .config("spark.sql.adaptive.skewJoin.enabled", "true") \\\n .config("spark.serializer", "org.apache.spark.serializer.KryoSerializer") \\\n .getOrCreate()\n'})}),"\n",(0,r.jsx)(n.h3,{id:"memory-management",children:"Memory Management"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:"# For large datasets, consider:\ndf = df.repartition(200) # Optimal partition count\ndf.cache() # Cache if reused multiple times\n"})}),"\n",(0,r.jsx)(n.h3,{id:"kafka-throughput",children:"Kafka Throughput"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# For high-throughput scenarios:\nclient.write_protobuf_df_to_kafka(\n proto_df,\n kafka_bootstrap_servers="brokers",\n kafka_topic="topic", \n kafka_num_batches=8, # Increase parallel writers\n additional_options={\n "kafka.batch.size": "65536", # Larger batches\n "kafka.linger.ms": "100", # Allow batching delay\n "kafka.compression.type": "lz4" # Fast compression\n }\n)\n'})}),"\n",(0,r.jsx)(n.h2,{id:"monitoring--debugging",children:"Monitoring & Debugging"}),"\n",(0,r.jsx)(n.h3,{id:"dataframe-inspection",children:"DataFrame Inspection"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Check data before processing\nprint(f"Records: {df.count()}")\nprint(f"Columns: {df.columns}")\ndf.printSchema()\ndf.show(5)\n\n# Check protobuf output\nproto_df.show(5, truncate=False)\nprint(f"Protobuf messages: {proto_df.count()}")\n'})}),"\n",(0,r.jsx)(n.h3,{id:"error-handling",children:"Error Handling"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'try:\n proto_df = client.generate_df_with_protobuf_messages(df)\n client.write_protobuf_df_to_kafka(proto_df, brokers, topic)\n \nexcept Exception as e:\n print(f"Pipeline failed: {e}")\n # Log to monitoring system\n # Send alerts\n raise\n'})}),"\n",(0,r.jsx)(n.h2,{id:"integration-with-other-sdks",children:"Integration with Other SDKs"}),"\n",(0,r.jsx)(n.h3,{id:"with-grpc-feature-client",children:"With gRPC Feature Client"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:"# Spark client pushes features to Kafka\nspark_client = OnlineFeatureStorePyClient(...)\nspark_client.write_protobuf_df_to_kafka(proto_df, brokers, topic)\n\n# gRPC client retrieves features in real-time\nfrom grpc_feature_client import GRPCFeatureClient\ngrpc_client = GRPCFeatureClient(config)\nfeatures = grpc_client.retrieve_decoded_features(...)\n"})}),"\n",(0,r.jsx)(n.h3,{id:"with-http-feature-client-bharatml_common",children:"With HTTP Feature Client (bharatml_common)"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:"# Use HTTP client for metadata validation\nfrom bharatml_common import HTTPFeatureClient\nhttp_client = HTTPFeatureClient(base_url, job_id, token)\nmetadata = http_client.get_feature_metadata()\n\n# Validate feature names using shared utilities\nfrom bharatml_common import clean_column_name\nclean_features = [clean_column_name(name) for name in feature_names]\n\n# Process with Spark client\nspark_client.generate_df_with_protobuf_messages(df)\n"})}),"\n",(0,r.jsx)(n.h2,{id:"common-use-cases",children:"Common Use Cases"}),"\n",(0,r.jsx)(n.h3,{id:"1-daily-batch-etl",children:"1. Daily Batch ETL"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# Cron job: 0 2 * * * (daily at 2 AM)\nspark-submit \\\n --packages org.apache.spark:spark-sql-kafka-0-10_2.12:3.4.0 \\\n --conf spark.sql.adaptive.enabled=true \\\n daily_feature_pipeline.py\n"})}),"\n",(0,r.jsx)(n.h3,{id:"2-historical-backfill",children:"2. Historical Backfill"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Backfill last 30 days\nfrom datetime import datetime, timedelta\n\nfor i in range(30):\n date = datetime.now() - timedelta(days=i)\n df = spark.sql(f"""\n SELECT * FROM features \n WHERE date = \'{date.strftime(\'%Y-%m-%d\')}\'\n """)\n \n proto_df = client.generate_df_with_protobuf_messages(df)\n client.write_protobuf_df_to_kafka(proto_df, brokers, f"backfill.{date.strftime(\'%Y%m%d\')}")\n'})}),"\n",(0,r.jsx)(n.h3,{id:"3-real-time-streaming-advanced",children:"3. Real-time Streaming (Advanced)"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Read from streaming source, process, and publish\nstreaming_df = spark.readStream \\\n .format("kafka") \\\n .option("kafka.bootstrap.servers", input_brokers) \\\n .option("subscribe", input_topic) \\\n .load()\n\n# Process streaming DataFrame\nprocessed_df = streaming_df.select(...)\n\n# Write to output Kafka (requires structured streaming)\nquery = processed_df.writeStream \\\n .format("kafka") \\\n .option("kafka.bootstrap.servers", output_brokers) \\\n .option("topic", output_topic) \\\n .start()\n'})}),"\n",(0,r.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,r.jsx)(n.h3,{id:"common-issues",children:"Common Issues"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"OutOfMemoryError"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Increase driver memory or reduce partition size\nspark.conf.set("spark.sql.adaptive.coalescePartitions.minPartitionNum", "50")\n'})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Kafka Connection Timeout"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Check network connectivity and broker addresses\nadditional_options = {\n "kafka.request.timeout.ms": "60000",\n "kafka.session.timeout.ms": "30000"\n}\n'})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Protobuf Serialization Errors"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'# Check data types and null values\ndf = df.fillna({"string_col": "", "numeric_col": 0})\n'})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Metadata API Errors"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:"# Verify job_id, job_token, and URL\n# Check API server logs\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"debug-mode",children:"Debug Mode"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'import logging\nlogging.basicConfig(level=logging.DEBUG)\n\n# Enable Spark SQL logging\nspark.sparkContext.setLogLevel("INFO")\n'})}),"\n",(0,r.jsx)(n.h2,{id:"migration-from-legacy-clients",children:"Migration from Legacy Clients"}),"\n",(0,r.jsx)(n.p,{children:"If migrating from older versions:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:"# Old import\n# from online_feature_store_py_client import OnlineFeatureStorePyClient\n\n# New import (same interface)\nfrom spark_feature_push_client import OnlineFeatureStorePyClient\n\n# API remains the same - no code changes needed!\n"})}),"\n",(0,r.jsx)(n.h2,{id:"best-practices",children:"Best Practices"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Resource Management"}),": Always stop Spark sessions"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Error Handling"}),": Implement proper exception handling and retries"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Monitoring"}),": Add metrics and logging to your pipelines"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Testing"}),": Test with sample data before production runs"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Security"}),": Use secure Kafka configurations in production"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Performance"}),": Monitor Spark UI for optimization opportunities"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The Spark Feature Push Client is your gateway from batch data sources to the real-time online feature store! \ud83d\ude80"}),"\n",(0,r.jsx)(n.h2,{id:"contributing-1",children:"Contributing"}),"\n",(0,r.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,r.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\ud83d\udcac ",(0,r.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,r.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,r.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,r.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,r.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,r.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"license-1",children:"License"}),"\n",(0,r.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,r.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)("div",{align:"center",children:(0,r.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,r.jsx)("div",{align:"center",children:(0,r.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>o});var t=a(6540);const r={},i=t.createContext(r);function s(e){const n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/adb039a4.c0c263a3.js b/docs/assets/js/adb039a4.c0c263a3.js new file mode 100644 index 00000000..e0723da8 --- /dev/null +++ b/docs/assets/js/adb039a4.c0c263a3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7609],{926:a=>{a.exports=JSON.parse('{"tag":{"label":"llm","permalink":"/BharatMLStack/blog/tags/llm","allTagsPath":"/BharatMLStack/blog/tags","count":2,"unlisted":false},"listMetadata":{"permalink":"/BharatMLStack/blog/tags/llm","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/be9e6e2d.944ea2f0.js b/docs/assets/js/be9e6e2d.944ea2f0.js new file mode 100644 index 00000000..1c4c7230 --- /dev/null +++ b/docs/assets/js/be9e6e2d.944ea2f0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7871],{3405:a=>{a.exports=JSON.parse('{"tag":{"label":"embedding-search","permalink":"/BharatMLStack/blog/tags/embedding-search","allTagsPath":"/BharatMLStack/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/BharatMLStack/blog/tags/embedding-search","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/c4822c4f.9fe3ec4e.js b/docs/assets/js/c4822c4f.c80625fe.js similarity index 98% rename from docs/assets/js/c4822c4f.9fe3ec4e.js rename to docs/assets/js/c4822c4f.c80625fe.js index bf79f6f5..8c408293 100644 --- a/docs/assets/js/c4822c4f.9fe3ec4e.js +++ b/docs/assets/js/c4822c4f.c80625fe.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1915],{3649:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"online-feature-store/v1.0.0/functionalities","title":"Key Functionalities","description":"Overview","source":"@site/docs/online-feature-store/v1.0.0/functionalities.md","sourceDirName":"online-feature-store/v1.0.0","slug":"/online-feature-store/v1.0.0/functionalities","permalink":"/BharatMLStack/online-feature-store/v1.0.0/functionalities","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/online-feature-store/v1.0.0/functionalities.md","tags":[],"version":"current","sidebarPosition":4,"frontMatter":{"title":"Key Functionalities","sidebar_position":4},"sidebar":"tutorialSidebar","previous":{"title":"Benchmarks","permalink":"/BharatMLStack/online-feature-store/v1.0.0/benchmarks"},"next":{"title":"Release Notes","permalink":"/BharatMLStack/online-feature-store/v1.0.0/release-notes"}}');var s=r(4848),t=r(8453);const l={title:"Key Functionalities",sidebar_position:4},o="Online Feature Store - Key Functionalities",a={},c=[{value:"Overview",id:"overview",level:2},{value:"\ud83d\ude80 Core Capabilities",id:"-core-capabilities",level:2},{value:"<strong>Real-Time Feature Serving</strong>",id:"real-time-feature-serving",level:3},{value:"<strong>Multi-Format Data Support</strong>",id:"multi-format-data-support",level:3},{value:"<strong>Multi-Database Backend</strong>",id:"multi-database-backend",level:3},{value:"\ud83c\udfaf Key Features",id:"-key-features",level:2},{value:"<strong>Performance Optimizations</strong>",id:"performance-optimizations",level:3},{value:"<strong>Data Management</strong>",id:"data-management",level:3},{value:"<strong>Developer Experience</strong>",id:"developer-experience",level:3},{value:"<strong>Production Ready</strong>",id:"production-ready",level:3},{value:"\ud83d\udcca Use Cases",id:"-use-cases",level:2},{value:"<strong>Real-Time ML Inference</strong>",id:"real-time-ml-inference",level:3},{value:"<strong>Batch Feature Serving</strong>",id:"batch-feature-serving",level:3},{value:"<strong>A/B Testing Support</strong>",id:"ab-testing-support",level:3},{value:"\ud83c\udf9b\ufe0f Configuration Options",id:"\ufe0f-configuration-options",level:2},{value:"<strong>Performance Tuning</strong>",id:"performance-tuning",level:3},{value:"<strong>Storage Configuration</strong>",id:"storage-configuration",level:3},{value:"<strong>Monitoring & Observability</strong>",id:"monitoring--observability",level:3},{value:"\ud83d\udcc8 Production Deployment",id:"-production-deployment",level:2},{value:"<strong>Recommended Architecture</strong>",id:"recommended-architecture",level:3},{value:"<strong>Scaling Guidelines</strong>",id:"scaling-guidelines",level:3},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"online-feature-store---key-functionalities",children:"Online Feature Store - Key Functionalities"})}),"\n",(0,s.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,s.jsxs)(n.p,{children:["The BharatML Online Feature Store is a high-performance, production-ready system designed to serve machine learning features with ",(0,s.jsx)(n.strong,{children:"sub-10ms P99 latency"})," and ",(0,s.jsx)(n.strong,{children:"1M+ RPS capacity"}),". It bridges the gap between offline feature engineering and real-time model inference."]}),"\n",(0,s.jsx)(n.h2,{id:"-core-capabilities",children:"\ud83d\ude80 Core Capabilities"}),"\n",(0,s.jsx)(n.h3,{id:"real-time-feature-serving",children:(0,s.jsx)(n.strong,{children:"Real-Time Feature Serving"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Ultra-Low Latency"}),": Sub-10ms P99 response times"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"High Throughput"}),": Tested at 1M+ requests per second with 100 IDs per request"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Batch Retrieval"}),": Fetch multiple features for multiple entities in a single request"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Point-in-Time Consistency"}),": Ensure feature consistency across model predictions"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Dependent feature consistency"}),": features part of same feature group."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"multi-format-data-support",children:(0,s.jsx)(n.strong,{children:"Multi-Format Data Support"})}),"\n",(0,s.jsx)(n.p,{children:"Supports all common ML data types with optimized serialization:"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Data Type"}),(0,s.jsx)(n.th,{children:"Support"}),(0,s.jsx)(n.th,{children:"Use Cases"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Integers"})}),(0,s.jsx)(n.td,{children:"int8, int16, int32, int64"}),(0,s.jsx)(n.td,{children:"User IDs, counts, categorical encodings"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Floats"})}),(0,s.jsx)(n.td,{children:"float16, float32, float64"}),(0,s.jsx)(n.td,{children:"Continuous features, embeddings, scores"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Strings"})}),(0,s.jsx)(n.td,{children:"Variable length"}),(0,s.jsx)(n.td,{children:"Categories, text features, metadata"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Booleans"})}),(0,s.jsx)(n.td,{children:"Bit-packed"}),(0,s.jsx)(n.td,{children:"Feature flags, binary indicators"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Vectors"})}),(0,s.jsx)(n.td,{children:"All above types"}),(0,s.jsx)(n.td,{children:"Embeddings, feature arrays, time series"})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"multi-database-backend",children:(0,s.jsx)(n.strong,{children:"Multi-Database Backend"})}),"\n",(0,s.jsx)(n.p,{children:"Flexible storage options for different deployment needs:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"\ud83d\udd25 Scylla DB"}),": Ultra-high performance NoSQL (recommended for production)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"\u26a1 Dragonfly"}),": Modern Redis alternative with better memory efficiency"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"\ud83d\udcca Redis"}),": Standard in-memory store for development and small-scale deployments"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"-key-features",children:"\ud83c\udfaf Key Features"}),"\n",(0,s.jsx)(n.h3,{id:"performance-optimizations",children:(0,s.jsx)(n.strong,{children:"Performance Optimizations"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Custom PSDB Format"}),": Proprietary serialization format optimized for ML features"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Object Pooling"}),": Memory-efficient resource reuse"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Connection Pooling"}),": Optimized database connection management"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Compression Support"}),": Multiple algorithms (LZ4, Snappy, ZSTD) with intelligent fallback"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"data-management",children:(0,s.jsx)(n.strong,{children:"Data Management"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"TTL Support"}),": Automatic feature expiration with configurable time-to-live"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Versioning"}),": Multiple feature schema versions with backward compatibility"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Batch Operations"}),": Efficient bulk read/write operations"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature Groups"}),": Logical grouping of related features for better organization"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"developer-experience",children:(0,s.jsx)(n.strong,{children:"Developer Experience"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"gRPC API"}),": High-performance, language-agnostic interface"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Go SDK"}),": Native Go client with connection pooling and error handling"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Python SDK"}),": ML-friendly Python bindings for data scientists"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"RESTful Interface"}),": HTTP API for health check"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"production-ready",children:(0,s.jsx)(n.strong,{children:"Production Ready"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Health Checks"}),": Built-in monitoring and health endpoints"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Metrics Integration"}),": DataDog, Prometheus-compatible metrics"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Structured Logging"}),": JSON-formatted logs with configurable levels"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Graceful Shutdown"}),": Clean resource cleanup on termination"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"-use-cases",children:"\ud83d\udcca Use Cases"}),"\n",(0,s.jsx)(n.h3,{id:"real-time-ml-inference",children:(0,s.jsx)(n.strong,{children:"Real-Time ML Inference"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'// Fetch user features for recommendation model\nquery := &onfs.Query{\n EntityLabel: "user",\n FeatureGroups: []onfs.FeatureGroup{\n {\n Label: "demographics",\n FeatureLabels: []string{"age", "location", "income"},\n },\n {\n Label: "behavior", \n FeatureLabels: []string{"click_rate", "purchase_history"},\n },\n },\n KeysSchema: []string{"user_id"},\n Keys: []onfs.Keys{\n {Cols: []string{"user_123"}},\n },\n}\n\nresult, err := client.RetrieveFeatures(ctx, query)\n'})}),"\n",(0,s.jsx)(n.h3,{id:"batch-feature-serving",children:(0,s.jsx)(n.strong,{children:"Batch Feature Serving"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'// Bulk feature retrieval for model training\nquery := &onfs.Query{\n EntityLabel: "transaction",\n FeatureGroups: []onfs.FeatureGroup{\n {\n Label: "transaction_history",\n FeatureLabels: []string{"amount", "frequency", "merchant_type"},\n },\n {\n Label: "risk_scores",\n FeatureLabels: []string{"fraud_score", "credit_score"},\n },\n },\n KeysSchema: []string{"transaction_id"},\n Keys: []onfs.Keys{\n {Cols: []string{"txn_001"}},\n {Cols: []string{"txn_002"}},\n // ... 100s of transaction IDs\n },\n}\n\nresult, err := client.RetrieveFeatures(ctx, query)\n'})}),"\n",(0,s.jsx)(n.h3,{id:"ab-testing-support",children:(0,s.jsx)(n.strong,{children:"A/B Testing Support"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'// Version-aware feature retrieval with decoded values\nquery := &onfs.Query{\n EntityLabel: "experiment",\n FeatureGroups: []onfs.FeatureGroup{\n {\n Label: "model_features_v2", // Specific version\n FeatureLabels: []string{"feature_a", "feature_b", "feature_c"},\n },\n },\n KeysSchema: []string{"user_id"},\n Keys: []onfs.Keys{\n {Cols: []string{"user_123"}},\n },\n}\n\n// Get string-decoded values for easier debugging/analysis\ndecodedResult, err := client.RetrieveDecodedFeatures(ctx, query)\n'})}),"\n",(0,s.jsx)(n.h2,{id:"\ufe0f-configuration-options",children:"\ud83c\udf9b\ufe0f Configuration Options"}),"\n",(0,s.jsx)(n.h3,{id:"performance-tuning",children:(0,s.jsx)(n.strong,{children:"Performance Tuning"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Cache TTL"}),": Configure feature freshness requirements"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"storage-configuration",children:(0,s.jsx)(n.strong,{children:"Storage Configuration"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Database Selection"}),": Choose backend based on scale and requirements"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Replication Factor"}),": RF=2 for ScyllaDB"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Partition Strategy"}),": DB side control - not handled here"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Backup Frequency"}),": DB side control - not handled here"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"monitoring--observability",children:(0,s.jsx)(n.strong,{children:"Monitoring & Observability"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Metrics Collection"}),": Request rates, latencies, error rates"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Custom Dashboards"}),": Feature-specific monitoring views"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"-production-deployment",children:"\ud83d\udcc8 Production Deployment"}),"\n",(0,s.jsx)(n.h3,{id:"recommended-architecture",children:(0,s.jsx)(n.strong,{children:"Recommended Architecture"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Load Balancer"}),": Distribute traffic across multiple instances"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature Store Cluster"}),": 3+ instances for high availability"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Database Cluster"}),": Replicated backend with automatic failover"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Monitoring Stack"}),": Metrics, logs, and alerting infrastructure"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"scaling-guidelines",children:(0,s.jsx)(n.strong,{children:"Scaling Guidelines"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Horizontal Scaling"}),": Add more feature store instances"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Database Scaling"}),": Increase partition count or upgrade hardware"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Dragonfly/Remote Cache Scaling"}),": Use Cluster or Failover/Sentinal based setup"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Connection Tuning"}),": Optimize pool sizes for your traffic patterns"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,s.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,s.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\ud83d\udcac ",(0,s.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,s.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,s.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,s.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,s.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,s.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,s.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,s.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)("div",{align:"center",children:(0,s.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,s.jsx)("div",{align:"center",children:(0,s.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},8453:(e,n,r)=>{r.d(n,{R:()=>l,x:()=>o});var i=r(6540);const s={},t=i.createContext(s);function l(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1915],{3649:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"online-feature-store/v1.0.0/functionalities","title":"Key Functionalities","description":"Overview","source":"@site/docs/online-feature-store/v1.0.0/functionalities.md","sourceDirName":"online-feature-store/v1.0.0","slug":"/online-feature-store/v1.0.0/functionalities","permalink":"/BharatMLStack/online-feature-store/v1.0.0/functionalities","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/online-feature-store/v1.0.0/functionalities.md","tags":[],"version":"current","sidebarPosition":4,"frontMatter":{"title":"Key Functionalities","sidebar_position":4},"sidebar":"tutorialSidebar","previous":{"title":"Benchmarks","permalink":"/BharatMLStack/online-feature-store/v1.0.0/benchmarks"},"next":{"title":"Release Notes","permalink":"/BharatMLStack/online-feature-store/v1.0.0/release-notes"}}');var s=r(4848),t=r(8453);const l={title:"Key Functionalities",sidebar_position:4},o="Online Feature Store - Key Functionalities",a={},c=[{value:"Overview",id:"overview",level:2},{value:"\ud83d\ude80 Core Capabilities",id:"-core-capabilities",level:2},{value:"<strong>Real-Time Feature Serving</strong>",id:"real-time-feature-serving",level:3},{value:"<strong>Multi-Format Data Support</strong>",id:"multi-format-data-support",level:3},{value:"<strong>Multi-Database Backend</strong>",id:"multi-database-backend",level:3},{value:"\ud83c\udfaf Key Features",id:"-key-features",level:2},{value:"<strong>Performance Optimizations</strong>",id:"performance-optimizations",level:3},{value:"<strong>Data Management</strong>",id:"data-management",level:3},{value:"<strong>Developer Experience</strong>",id:"developer-experience",level:3},{value:"<strong>Production Ready</strong>",id:"production-ready",level:3},{value:"\ud83d\udcca Use Cases",id:"-use-cases",level:2},{value:"<strong>Real-Time ML Inference</strong>",id:"real-time-ml-inference",level:3},{value:"<strong>Batch Feature Serving</strong>",id:"batch-feature-serving",level:3},{value:"<strong>A/B Testing Support</strong>",id:"ab-testing-support",level:3},{value:"\ud83c\udf9b\ufe0f Configuration Options",id:"\ufe0f-configuration-options",level:2},{value:"<strong>Performance Tuning</strong>",id:"performance-tuning",level:3},{value:"<strong>Storage Configuration</strong>",id:"storage-configuration",level:3},{value:"<strong>Monitoring & Observability</strong>",id:"monitoring--observability",level:3},{value:"\ud83d\udcc8 Production Deployment",id:"-production-deployment",level:2},{value:"<strong>Recommended Architecture</strong>",id:"recommended-architecture",level:3},{value:"<strong>Scaling Guidelines</strong>",id:"scaling-guidelines",level:3},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"online-feature-store---key-functionalities",children:"Online Feature Store - Key Functionalities"})}),"\n",(0,s.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,s.jsxs)(n.p,{children:["The BharatML Online Feature Store is a high-performance, production-ready system designed to serve machine learning features with ",(0,s.jsx)(n.strong,{children:"sub-10ms P99 latency"})," and ",(0,s.jsx)(n.strong,{children:"1M+ RPS capacity"}),". It bridges the gap between offline feature engineering and real-time model inference."]}),"\n",(0,s.jsx)(n.h2,{id:"-core-capabilities",children:"\ud83d\ude80 Core Capabilities"}),"\n",(0,s.jsx)(n.h3,{id:"real-time-feature-serving",children:(0,s.jsx)(n.strong,{children:"Real-Time Feature Serving"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Ultra-Low Latency"}),": Sub-10ms P99 response times"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"High Throughput"}),": Tested at 1M+ requests per second with 100 IDs per request"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Batch Retrieval"}),": Fetch multiple features for multiple entities in a single request"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Point-in-Time Consistency"}),": Ensure feature consistency across model predictions"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Dependent feature consistency"}),": features part of same feature group."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"multi-format-data-support",children:(0,s.jsx)(n.strong,{children:"Multi-Format Data Support"})}),"\n",(0,s.jsx)(n.p,{children:"Supports all common ML data types with optimized serialization:"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Data Type"}),(0,s.jsx)(n.th,{children:"Support"}),(0,s.jsx)(n.th,{children:"Use Cases"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Integers"})}),(0,s.jsx)(n.td,{children:"int8, int16, int32, int64"}),(0,s.jsx)(n.td,{children:"User IDs, counts, categorical encodings"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Floats"})}),(0,s.jsx)(n.td,{children:"float16, float32, float64"}),(0,s.jsx)(n.td,{children:"Continuous features, embeddings, scores"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Strings"})}),(0,s.jsx)(n.td,{children:"Variable length"}),(0,s.jsx)(n.td,{children:"Categories, text features, metadata"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Booleans"})}),(0,s.jsx)(n.td,{children:"Bit-packed"}),(0,s.jsx)(n.td,{children:"Feature flags, binary indicators"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Vectors"})}),(0,s.jsx)(n.td,{children:"All above types"}),(0,s.jsx)(n.td,{children:"Embeddings, feature arrays, time series"})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"multi-database-backend",children:(0,s.jsx)(n.strong,{children:"Multi-Database Backend"})}),"\n",(0,s.jsx)(n.p,{children:"Flexible storage options for different deployment needs:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"\ud83d\udd25 Scylla DB"}),": Ultra-high performance NoSQL (recommended for production)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"\u26a1 Dragonfly"}),": Modern Redis alternative with better memory efficiency"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"\ud83d\udcca Redis"}),": Standard in-memory store for development and small-scale deployments"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"-key-features",children:"\ud83c\udfaf Key Features"}),"\n",(0,s.jsx)(n.h3,{id:"performance-optimizations",children:(0,s.jsx)(n.strong,{children:"Performance Optimizations"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Custom PSDB Format"}),": Proprietary serialization format optimized for ML features"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Object Pooling"}),": Memory-efficient resource reuse"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Connection Pooling"}),": Optimized database connection management"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Compression Support"}),": Multiple algorithms (LZ4, Snappy, ZSTD) with intelligent fallback"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"data-management",children:(0,s.jsx)(n.strong,{children:"Data Management"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"TTL Support"}),": Automatic feature expiration with configurable time-to-live"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Versioning"}),": Multiple feature schema versions with backward compatibility"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Batch Operations"}),": Efficient bulk read/write operations"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature Groups"}),": Logical grouping of related features for better organization"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"developer-experience",children:(0,s.jsx)(n.strong,{children:"Developer Experience"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"gRPC API"}),": High-performance, language-agnostic interface"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Go SDK"}),": Native Go client with connection pooling and error handling"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Python SDK"}),": ML-friendly Python bindings for data scientists"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"RESTful Interface"}),": HTTP API for health check"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"production-ready",children:(0,s.jsx)(n.strong,{children:"Production Ready"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Health Checks"}),": Built-in monitoring and health endpoints"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Metrics Integration"}),": DataDog, Prometheus-compatible metrics"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Structured Logging"}),": JSON-formatted logs with configurable levels"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Graceful Shutdown"}),": Clean resource cleanup on termination"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"-use-cases",children:"\ud83d\udcca Use Cases"}),"\n",(0,s.jsx)(n.h3,{id:"real-time-ml-inference",children:(0,s.jsx)(n.strong,{children:"Real-Time ML Inference"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'// Fetch user features for recommendation model\nquery := &onfs.Query{\n EntityLabel: "user",\n FeatureGroups: []onfs.FeatureGroup{\n {\n Label: "demographics",\n FeatureLabels: []string{"age", "location", "income"},\n },\n {\n Label: "behavior", \n FeatureLabels: []string{"click_rate", "purchase_history"},\n },\n },\n KeysSchema: []string{"user_id"},\n Keys: []onfs.Keys{\n {Cols: []string{"user_123"}},\n },\n}\n\nresult, err := client.RetrieveFeatures(ctx, query)\n'})}),"\n",(0,s.jsx)(n.h3,{id:"batch-feature-serving",children:(0,s.jsx)(n.strong,{children:"Batch Feature Serving"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'// Bulk feature retrieval for model training\nquery := &onfs.Query{\n EntityLabel: "transaction",\n FeatureGroups: []onfs.FeatureGroup{\n {\n Label: "transaction_history",\n FeatureLabels: []string{"amount", "frequency", "merchant_type"},\n },\n {\n Label: "risk_scores",\n FeatureLabels: []string{"fraud_score", "credit_score"},\n },\n },\n KeysSchema: []string{"transaction_id"},\n Keys: []onfs.Keys{\n {Cols: []string{"txn_001"}},\n {Cols: []string{"txn_002"}},\n // ... 100s of transaction IDs\n },\n}\n\nresult, err := client.RetrieveFeatures(ctx, query)\n'})}),"\n",(0,s.jsx)(n.h3,{id:"ab-testing-support",children:(0,s.jsx)(n.strong,{children:"A/B Testing Support"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'// Version-aware feature retrieval with decoded values\nquery := &onfs.Query{\n EntityLabel: "experiment",\n FeatureGroups: []onfs.FeatureGroup{\n {\n Label: "model_features_v2", // Specific version\n FeatureLabels: []string{"feature_a", "feature_b", "feature_c"},\n },\n },\n KeysSchema: []string{"user_id"},\n Keys: []onfs.Keys{\n {Cols: []string{"user_123"}},\n },\n}\n\n// Get string-decoded values for easier debugging/analysis\ndecodedResult, err := client.RetrieveDecodedFeatures(ctx, query)\n'})}),"\n",(0,s.jsx)(n.h2,{id:"\ufe0f-configuration-options",children:"\ud83c\udf9b\ufe0f Configuration Options"}),"\n",(0,s.jsx)(n.h3,{id:"performance-tuning",children:(0,s.jsx)(n.strong,{children:"Performance Tuning"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Cache TTL"}),": Configure feature freshness requirements"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"storage-configuration",children:(0,s.jsx)(n.strong,{children:"Storage Configuration"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Database Selection"}),": Choose backend based on scale and requirements"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Replication Factor"}),": RF=2 for ScyllaDB"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Partition Strategy"}),": DB side control - not handled here"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Backup Frequency"}),": DB side control - not handled here"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"monitoring--observability",children:(0,s.jsx)(n.strong,{children:"Monitoring & Observability"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Metrics Collection"}),": Request rates, latencies, error rates"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Custom Dashboards"}),": Feature-specific monitoring views"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"-production-deployment",children:"\ud83d\udcc8 Production Deployment"}),"\n",(0,s.jsx)(n.h3,{id:"recommended-architecture",children:(0,s.jsx)(n.strong,{children:"Recommended Architecture"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Load Balancer"}),": Distribute traffic across multiple instances"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature Store Cluster"}),": 3+ instances for high availability"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Database Cluster"}),": Replicated backend with automatic failover"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Monitoring Stack"}),": Metrics, logs, and alerting infrastructure"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"scaling-guidelines",children:(0,s.jsx)(n.strong,{children:"Scaling Guidelines"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Horizontal Scaling"}),": Add more feature store instances"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Database Scaling"}),": Increase partition count or upgrade hardware"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Dragonfly/Remote Cache Scaling"}),": Use Cluster or Failover/Sentinal based setup"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Connection Tuning"}),": Optimize pool sizes for your traffic patterns"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,s.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,s.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\ud83d\udcac ",(0,s.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,s.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,s.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,s.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,s.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,s.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,s.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,s.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,s.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)("div",{align:"center",children:(0,s.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,s.jsx)("div",{align:"center",children:(0,s.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},8453:(e,n,r)=>{r.d(n,{R:()=>l,x:()=>o});var i=r(6540);const s={},t=i.createContext(s);function l(e){const n=i.useContext(t);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/c4f5d8e4.41d5b3c8.js b/docs/assets/js/c4f5d8e4.41d5b3c8.js new file mode 100644 index 00000000..69b0d45b --- /dev/null +++ b/docs/assets/js/c4f5d8e4.41d5b3c8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2634],{6467:(e,i,t)=>{t.r(i),t.d(i,{default:()=>M});var s=t(4164),r=t(8774),n=t(4586),a=t(6025),o=t(1656),c=t(1107);const l={features:"features_t9lD",featureSvg:"featureSvg_GfXr",featuresHeader:"featuresHeader_qR2i",featuresSubtitle:"featuresSubtitle_VdGe","bharatml-card":"bharatml-card_xZ6l","bharatml-icon":"bharatml-icon_XBoJ",featureDescription:"featureDescription_sP1D"};var d=t(4848);const h=[{title:"High-Performance Feature Store",icon:"\ud83d\ude80",description:(0,d.jsx)(d.Fragment,{children:"Sub-10ms P99 latency and 1M+ RPS capacity. Built for real-time ML inference with custom PSDB serialization format that outperforms Protocol Buffers and Apache Arrow."})},{title:"Production-Ready ML Infrastructure",icon:"\u26a1",description:(0,d.jsx)(d.Fragment,{children:"Multi-database backends (Scylla, Dragonfly, Redis), comprehensive monitoring, and enterprise-grade features. Deploy with confidence using battle-tested components."})},{title:"Developer-First Experience",icon:"\ud83d\udee0\ufe0f",description:(0,d.jsx)(d.Fragment,{children:"Multi-language SDKs (Go, Python), gRPC APIs, and extensive documentation. From data scientists, ML engineers to backend engineers, everyone gets tools they love."})}],u=[{title:"Feature Catalog & Management",icon:"\ud83d\udccb",description:(0,d.jsx)(d.Fragment,{children:"Comprehensive feature catalog with metadata management, versioning, and governance. Organize and discover features across your ML platform with ease."})},{title:"User Management & Admin Ops",icon:"\ud83d\udc65",description:(0,d.jsx)(d.Fragment,{children:"Role-based access control, user authentication, and administrative operations. Secure your ML platform with enterprise-grade user management capabilities."})},{title:"Modern UI Framework",icon:"\ud83c\udfa8",description:(0,d.jsx)(d.Fragment,{children:"Intuitive, responsive web interface built with modern web technologies. Streamline MLOps workflows with beautiful and functional user experiences."})}],m=[{title:"Multi-Language Support",icon:"\ud83c\udf10",description:(0,d.jsx)(d.Fragment,{children:"Native SDKs for Go and Python with idiomatic APIs. Choose the language that fits your team's expertise and existing infrastructure."})},{title:"gRPC & REST APIs",icon:"\ud83d\udd17",description:(0,d.jsx)(d.Fragment,{children:"High-performance gRPC clients and REST APIs for seamless integration. Built-in support for streaming, batching, and async operations."})},{title:"Spark Integration",icon:"\u26a1",description:(0,d.jsx)(d.Fragment,{children:"Native Apache Spark integration for batch feature processing and ingestion. Scale your feature engineering workflows with distributed computing power."})}];function x({icon:e,title:i,description:t}){return(0,d.jsxs)("div",{className:(0,s.A)("col col--4"),children:[(0,d.jsx)("div",{className:"text--center",children:(0,d.jsx)("div",{className:"bharatml-icon",children:e})}),(0,d.jsxs)("div",{className:"text--center padding-horiz--md bharatml-card",children:[(0,d.jsx)(c.A,{as:"h3",children:i}),(0,d.jsx)("p",{className:l.featureDescription,children:t})]})]})}function p({title:e,subtitle:i,features:t}){return(0,d.jsx)("section",{className:l.features,children:(0,d.jsxs)("div",{className:"container",children:[(0,d.jsxs)("div",{className:"text--center margin-bottom--xl",children:[(0,d.jsx)(c.A,{as:"h2",className:l.featuresHeader,children:e}),(0,d.jsx)("p",{className:l.featuresSubtitle,children:i})]}),(0,d.jsx)("div",{className:"row",children:t.map((e,i)=>(0,d.jsx)(x,{...e},i))})]})})}function g(){return(0,d.jsx)(p,{title:"Online Feature Store",subtitle:"High-performance, production-ready feature serving for real-time ML inference",features:h})}function f(){return(0,d.jsx)(p,{title:"Trufflebox UI",subtitle:"Modern, feature-rich UI framework for comprehensive MLOps management",features:u})}function j(){return(0,d.jsx)(p,{title:"SDKs",subtitle:"Developer-friendly client libraries and APIs for seamless platform integration",features:m})}const b={heroBanner:"heroBanner_qdFl",logoContainer:"logoContainer_xdaK",heroLogo:"heroLogo_U6bI",buttons:"buttons_AeoN",statsContainer:"statsContainer_KpvY",statItem:"statItem_bwiZ",aboutSection:"aboutSection_udvw",highlightBox:"highlightBox_Uhe8"};function v(){const{siteConfig:e}=(0,n.A)();return(0,d.jsx)("header",{className:(0,s.A)("hero bharatml-hero",b.heroBanner),children:(0,d.jsxs)("div",{className:"container",children:[(0,d.jsx)("div",{className:b.logoContainer,children:(0,d.jsx)("img",{src:(0,a.Ay)("/img/logo.svg"),alt:"BharatMLStack Logo",className:b.heroLogo})}),(0,d.jsxs)(c.A,{as:"h1",className:"hero__title",children:["Welcome to ",e.title]}),(0,d.jsx)("p",{className:"hero__subtitle",children:"Open source, end-to-end ML infrastructure stack built for scale, speed, and simplicity."}),(0,d.jsxs)("div",{className:b.buttons,children:[(0,d.jsx)(r.A,{className:"button button--secondary button--lg margin-right--md bharatml-button",to:"/category/online-feature-store",children:"\ud83d\udcda Get Started"}),(0,d.jsx)(r.A,{className:"button button--outline button--secondary button--lg",href:"https://github.com/Meesho/BharatMLStack",target:"_blank",children:"\u2b50 Star on GitHub"})]}),(0,d.jsxs)("div",{className:b.statsContainer,children:[(0,d.jsxs)("div",{className:b.statItem,children:[(0,d.jsx)("strong",{children:"Sub-10ms"}),(0,d.jsx)("span",{children:"P99 Latency"})]}),(0,d.jsxs)("div",{className:b.statItem,children:[(0,d.jsx)("strong",{children:"1M+ RPS"}),(0,d.jsx)("span",{children:"Tested Capacity"})]}),(0,d.jsxs)("div",{className:b.statItem,children:[(0,d.jsx)("strong",{children:"Multi-DB"}),(0,d.jsx)("span",{children:"Support"})]})]})]})})}function N(){return(0,d.jsx)("section",{className:b.aboutSection,children:(0,d.jsx)("div",{className:"container",children:(0,d.jsxs)("div",{className:"row",children:[(0,d.jsxs)("div",{className:"col col--6",children:[(0,d.jsx)(c.A,{as:"h2",children:"Built for India's Scale"}),(0,d.jsx)("p",{children:"BharatMLStack is a comprehensive, production-ready machine learning infrastructure platform designed to democratize ML capabilities across India and beyond. Our mission is to provide a robust, scalable, and accessible ML stack that empowers organizations to build, deploy, and manage machine learning solutions at massive scale."}),(0,d.jsx)(r.A,{className:"button button--primary",to:"/category/online-feature-store",children:"Explore Online Feature Store \u2192"})]}),(0,d.jsx)("div",{className:"col col--6",children:(0,d.jsxs)("div",{className:b.highlightBox,children:[(0,d.jsx)("h3",{children:"\ud83c\udfc6 Key Achievements"}),(0,d.jsxs)("ul",{children:[(0,d.jsx)("li",{children:"\u2705 Sub-10ms P99 latency for real-time inference"}),(0,d.jsx)("li",{children:"\u2705 1M+ RPS tested with 100 IDs per request"}),(0,d.jsx)("li",{children:"\u2705 PSDB format outperforms Proto3 & Arrow"}),(0,d.jsx)("li",{children:"\u2705 Multi-database: Scylla, Dragonfly, Redis"}),(0,d.jsx)("li",{children:"\u2705 Production-ready with comprehensive monitoring"})]})]})})]})})})}function y(){return(0,d.jsx)("section",{className:b.aboutSection,children:(0,d.jsx)("div",{className:"container",children:(0,d.jsxs)("div",{className:"row",children:[(0,d.jsxs)("div",{className:"col col--6",children:[(0,d.jsx)(c.A,{as:"h2",children:"Modern MLOps Management"}),(0,d.jsx)("p",{children:"Trufflebox UI provides a comprehensive, modern web interface for managing your entire ML infrastructure. Built with cutting-edge web technologies, it delivers an intuitive experience for feature management, user administration, and operational oversight. Streamline your MLOps workflows with enterprise-grade UI components."}),(0,d.jsx)(r.A,{className:"button button--primary",to:"/category/trufflebox-ui",children:"Explore Trufflebox UI \u2192"})]}),(0,d.jsx)("div",{className:"col col--6",children:(0,d.jsxs)("div",{className:b.highlightBox,children:[(0,d.jsx)("h3",{children:"\ud83c\udfa8 UI Features"}),(0,d.jsxs)("ul",{children:[(0,d.jsx)("li",{children:"\u2705 Comprehensive feature catalog & discovery"}),(0,d.jsx)("li",{children:"\u2705 Role-based access control & user management"}),(0,d.jsx)("li",{children:"\u2705 Job, Store, Admin Ops management"}),(0,d.jsx)("li",{children:"\u2705 Approval flow for everything"}),(0,d.jsx)("li",{children:"\u2705 Responsive design for desktop & mobile"})]})]})})]})})})}function S(){return(0,d.jsx)("section",{className:b.aboutSection,children:(0,d.jsx)("div",{className:"container",children:(0,d.jsxs)("div",{className:"row",children:[(0,d.jsxs)("div",{className:"col col--6",children:[(0,d.jsx)(c.A,{as:"h2",children:"Developer-First Integration"}),(0,d.jsx)("p",{children:"Our SDKs are designed with developers in mind, providing idiomatic APIs for Go and Python that feel natural in your existing codebase. Whether you're building microservices, data pipelines, or ML applications, our SDKs provide the tools you need for seamless integration with BharatMLStack's powerful infrastructure."}),(0,d.jsx)(r.A,{className:"button button--primary",to:"/category/sdks",children:"Explore SDKs \u2192"})]}),(0,d.jsx)("div",{className:"col col--6",children:(0,d.jsxs)("div",{className:b.highlightBox,children:[(0,d.jsx)("h3",{children:"\ud83d\udee0\ufe0f Developer Tools"}),(0,d.jsxs)("ul",{children:[(0,d.jsx)("li",{children:"\u2705 Native Go & Python SDKs with type safety"}),(0,d.jsx)("li",{children:"\u2705 High-performance gRPC"}),(0,d.jsx)("li",{children:"\u2705 Apache Spark integration for publishing features"})]})]})})]})})})}function w(){return(0,d.jsx)("section",{className:b.aboutSection,children:(0,d.jsx)("div",{className:"container",children:(0,d.jsxs)("div",{className:"row",children:[(0,d.jsxs)("div",{className:"col col--6",children:[(0,d.jsx)(c.A,{as:"h2",children:"Numerix"}),(0,d.jsx)("p",{children:"Numerix is a mathematical compute engine for BharatML Stack. It is used to perform mathematical operations on matrices and vectors."}),(0,d.jsx)(r.A,{className:"button button--primary",to:"/category/numerix",children:"Explore Numerix \u2192"})]}),(0,d.jsx)("div",{className:"col col--6",children:(0,d.jsxs)("div",{className:b.highlightBox,children:[(0,d.jsx)("h3",{children:"\ud83d\udee0\ufe0f Numerix Features"}),(0,d.jsxs)("ul",{children:[(0,d.jsx)("li",{children:"\u2705 Postfix expression evaluation"}),(0,d.jsx)("li",{children:"\u2705 Vectorized math operations"}),(0,d.jsx)("li",{children:"\u2705 Typed evaluation"}),(0,d.jsx)("li",{children:"\u2705 Compiler-assisted SIMD"}),(0,d.jsx)("li",{children:"\u2705 ARM & AMD support"}),(0,d.jsx)("li",{children:"\u2705 Multi-arch builds"}),(0,d.jsx)("li",{children:"\u2705 Deterministic runtime"})]})]})})]})})})}function M(){const{siteConfig:e}=(0,n.A)();return(0,d.jsxs)(o.A,{title:`${e.title} - Open Source ML Infrastructure`,description:"Open source, end-to-end ML infrastructure stack built for scale, speed, and simplicity. Features high-performance Online Feature Store with sub-10ms latency.",children:[(0,d.jsx)(v,{}),(0,d.jsxs)("main",{children:[(0,d.jsx)(g,{}),(0,d.jsx)(N,{}),(0,d.jsx)(f,{}),(0,d.jsx)(y,{}),(0,d.jsx)(j,{}),(0,d.jsx)(S,{}),(0,d.jsx)(w,{})]})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/c4f5d8e4.f5d4db47.js b/docs/assets/js/c4f5d8e4.f5d4db47.js deleted file mode 100644 index 24625a06..00000000 --- a/docs/assets/js/c4f5d8e4.f5d4db47.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2634],{6467:(e,t,i)=>{i.r(t),i.d(t,{default:()=>w});var s=i(4164),r=i(8774),n=i(4586),a=i(6025),o=i(1656),c=i(1107);const l={features:"features_t9lD",featureSvg:"featureSvg_GfXr",featuresHeader:"featuresHeader_qR2i",featuresSubtitle:"featuresSubtitle_VdGe","bharatml-card":"bharatml-card_xZ6l","bharatml-icon":"bharatml-icon_XBoJ",featureDescription:"featureDescription_sP1D"};var d=i(4848);const h=[{title:"High-Performance Feature Store",icon:"\ud83d\ude80",description:(0,d.jsx)(d.Fragment,{children:"Sub-10ms P99 latency and 1M+ RPS capacity. Built for real-time ML inference with custom PSDB serialization format that outperforms Protocol Buffers and Apache Arrow."})},{title:"Production-Ready ML Infrastructure",icon:"\u26a1",description:(0,d.jsx)(d.Fragment,{children:"Multi-database backends (Scylla, Dragonfly, Redis), comprehensive monitoring, and enterprise-grade features. Deploy with confidence using battle-tested components."})},{title:"Developer-First Experience",icon:"\ud83d\udee0\ufe0f",description:(0,d.jsx)(d.Fragment,{children:"Multi-language SDKs (Go, Python), gRPC APIs, and extensive documentation. From data scientists, ML engineers to backend engineers, everyone gets tools they love."})}],u=[{title:"Feature Catalog & Management",icon:"\ud83d\udccb",description:(0,d.jsx)(d.Fragment,{children:"Comprehensive feature catalog with metadata management, versioning, and governance. Organize and discover features across your ML platform with ease."})},{title:"User Management & Admin Ops",icon:"\ud83d\udc65",description:(0,d.jsx)(d.Fragment,{children:"Role-based access control, user authentication, and administrative operations. Secure your ML platform with enterprise-grade user management capabilities."})},{title:"Modern UI Framework",icon:"\ud83c\udfa8",description:(0,d.jsx)(d.Fragment,{children:"Intuitive, responsive web interface built with modern web technologies. Streamline MLOps workflows with beautiful and functional user experiences."})}],m=[{title:"Multi-Language Support",icon:"\ud83c\udf10",description:(0,d.jsx)(d.Fragment,{children:"Native SDKs for Go and Python with idiomatic APIs. Choose the language that fits your team's expertise and existing infrastructure."})},{title:"gRPC & REST APIs",icon:"\ud83d\udd17",description:(0,d.jsx)(d.Fragment,{children:"High-performance gRPC clients and REST APIs for seamless integration. Built-in support for streaming, batching, and async operations."})},{title:"Spark Integration",icon:"\u26a1",description:(0,d.jsx)(d.Fragment,{children:"Native Apache Spark integration for batch feature processing and ingestion. Scale your feature engineering workflows with distributed computing power."})}];function g({icon:e,title:t,description:i}){return(0,d.jsxs)("div",{className:(0,s.A)("col col--4"),children:[(0,d.jsx)("div",{className:"text--center",children:(0,d.jsx)("div",{className:"bharatml-icon",children:e})}),(0,d.jsxs)("div",{className:"text--center padding-horiz--md bharatml-card",children:[(0,d.jsx)(c.A,{as:"h3",children:t}),(0,d.jsx)("p",{className:l.featureDescription,children:i})]})]})}function p({title:e,subtitle:t,features:i}){return(0,d.jsx)("section",{className:l.features,children:(0,d.jsxs)("div",{className:"container",children:[(0,d.jsxs)("div",{className:"text--center margin-bottom--xl",children:[(0,d.jsx)(c.A,{as:"h2",className:l.featuresHeader,children:e}),(0,d.jsx)("p",{className:l.featuresSubtitle,children:t})]}),(0,d.jsx)("div",{className:"row",children:i.map(((e,t)=>(0,d.jsx)(g,{...e},t)))})]})})}function x(){return(0,d.jsx)(p,{title:"Online Feature Store",subtitle:"High-performance, production-ready feature serving for real-time ML inference",features:h})}function f(){return(0,d.jsx)(p,{title:"Trufflebox UI",subtitle:"Modern, feature-rich UI framework for comprehensive MLOps management",features:u})}function j(){return(0,d.jsx)(p,{title:"SDKs",subtitle:"Developer-friendly client libraries and APIs for seamless platform integration",features:m})}const b={heroBanner:"heroBanner_qdFl",logoContainer:"logoContainer_xdaK",heroLogo:"heroLogo_U6bI",buttons:"buttons_AeoN",statsContainer:"statsContainer_KpvY",statItem:"statItem_bwiZ",aboutSection:"aboutSection_udvw",highlightBox:"highlightBox_Uhe8"};function v(){const{siteConfig:e}=(0,n.A)();return(0,d.jsx)("header",{className:(0,s.A)("hero bharatml-hero",b.heroBanner),children:(0,d.jsxs)("div",{className:"container",children:[(0,d.jsx)("div",{className:b.logoContainer,children:(0,d.jsx)("img",{src:(0,a.Ay)("/img/logo.svg"),alt:"BharatMLStack Logo",className:b.heroLogo})}),(0,d.jsxs)(c.A,{as:"h1",className:"hero__title",children:["Welcome to ",e.title]}),(0,d.jsx)("p",{className:"hero__subtitle",children:"Open source, end-to-end ML infrastructure stack built for scale, speed, and simplicity."}),(0,d.jsxs)("div",{className:b.buttons,children:[(0,d.jsx)(r.A,{className:"button button--secondary button--lg margin-right--md bharatml-button",to:"/category/online-feature-store",children:"\ud83d\udcda Get Started"}),(0,d.jsx)(r.A,{className:"button button--outline button--secondary button--lg",href:"https://github.com/Meesho/BharatMLStack",target:"_blank",children:"\u2b50 Star on GitHub"})]}),(0,d.jsxs)("div",{className:b.statsContainer,children:[(0,d.jsxs)("div",{className:b.statItem,children:[(0,d.jsx)("strong",{children:"Sub-10ms"}),(0,d.jsx)("span",{children:"P99 Latency"})]}),(0,d.jsxs)("div",{className:b.statItem,children:[(0,d.jsx)("strong",{children:"1M+ RPS"}),(0,d.jsx)("span",{children:"Tested Capacity"})]}),(0,d.jsxs)("div",{className:b.statItem,children:[(0,d.jsx)("strong",{children:"Multi-DB"}),(0,d.jsx)("span",{children:"Support"})]})]})]})})}function y(){return(0,d.jsx)("section",{className:b.aboutSection,children:(0,d.jsx)("div",{className:"container",children:(0,d.jsxs)("div",{className:"row",children:[(0,d.jsxs)("div",{className:"col col--6",children:[(0,d.jsx)(c.A,{as:"h2",children:"Built for India's Scale"}),(0,d.jsx)("p",{children:"BharatMLStack is a comprehensive, production-ready machine learning infrastructure platform designed to democratize ML capabilities across India and beyond. Our mission is to provide a robust, scalable, and accessible ML stack that empowers organizations to build, deploy, and manage machine learning solutions at massive scale."}),(0,d.jsx)(r.A,{className:"button button--primary",to:"/category/online-feature-store",children:"Explore Online Feature Store \u2192"})]}),(0,d.jsx)("div",{className:"col col--6",children:(0,d.jsxs)("div",{className:b.highlightBox,children:[(0,d.jsx)("h3",{children:"\ud83c\udfc6 Key Achievements"}),(0,d.jsxs)("ul",{children:[(0,d.jsx)("li",{children:"\u2705 Sub-10ms P99 latency for real-time inference"}),(0,d.jsx)("li",{children:"\u2705 1M+ RPS tested with 100 IDs per request"}),(0,d.jsx)("li",{children:"\u2705 PSDB format outperforms Proto3 & Arrow"}),(0,d.jsx)("li",{children:"\u2705 Multi-database: Scylla, Dragonfly, Redis"}),(0,d.jsx)("li",{children:"\u2705 Production-ready with comprehensive monitoring"})]})]})})]})})})}function S(){return(0,d.jsx)("section",{className:b.aboutSection,children:(0,d.jsx)("div",{className:"container",children:(0,d.jsxs)("div",{className:"row",children:[(0,d.jsxs)("div",{className:"col col--6",children:[(0,d.jsx)(c.A,{as:"h2",children:"Modern MLOps Management"}),(0,d.jsx)("p",{children:"Trufflebox UI provides a comprehensive, modern web interface for managing your entire ML infrastructure. Built with cutting-edge web technologies, it delivers an intuitive experience for feature management, user administration, and operational oversight. Streamline your MLOps workflows with enterprise-grade UI components."}),(0,d.jsx)(r.A,{className:"button button--primary",to:"/category/trufflebox-ui",children:"Explore Trufflebox UI \u2192"})]}),(0,d.jsx)("div",{className:"col col--6",children:(0,d.jsxs)("div",{className:b.highlightBox,children:[(0,d.jsx)("h3",{children:"\ud83c\udfa8 UI Features"}),(0,d.jsxs)("ul",{children:[(0,d.jsx)("li",{children:"\u2705 Comprehensive feature catalog & discovery"}),(0,d.jsx)("li",{children:"\u2705 Role-based access control & user management"}),(0,d.jsx)("li",{children:"\u2705 Job, Store, Admin Ops management"}),(0,d.jsx)("li",{children:"\u2705 Approval flow for everything"}),(0,d.jsx)("li",{children:"\u2705 Responsive design for desktop & mobile"})]})]})})]})})})}function N(){return(0,d.jsx)("section",{className:b.aboutSection,children:(0,d.jsx)("div",{className:"container",children:(0,d.jsxs)("div",{className:"row",children:[(0,d.jsxs)("div",{className:"col col--6",children:[(0,d.jsx)(c.A,{as:"h2",children:"Developer-First Integration"}),(0,d.jsx)("p",{children:"Our SDKs are designed with developers in mind, providing idiomatic APIs for Go and Python that feel natural in your existing codebase. Whether you're building microservices, data pipelines, or ML applications, our SDKs provide the tools you need for seamless integration with BharatMLStack's powerful infrastructure."}),(0,d.jsx)(r.A,{className:"button button--primary",to:"/category/sdks",children:"Explore SDKs \u2192"})]}),(0,d.jsx)("div",{className:"col col--6",children:(0,d.jsxs)("div",{className:b.highlightBox,children:[(0,d.jsx)("h3",{children:"\ud83d\udee0\ufe0f Developer Tools"}),(0,d.jsxs)("ul",{children:[(0,d.jsx)("li",{children:"\u2705 Native Go & Python SDKs with type safety"}),(0,d.jsx)("li",{children:"\u2705 High-performance gRPC"}),(0,d.jsx)("li",{children:"\u2705 Apache Spark integration for publishing features"})]})]})})]})})})}function w(){const{siteConfig:e}=(0,n.A)();return(0,d.jsxs)(o.A,{title:`${e.title} - Open Source ML Infrastructure`,description:"Open source, end-to-end ML infrastructure stack built for scale, speed, and simplicity. Features high-performance Online Feature Store with sub-10ms latency.",children:[(0,d.jsx)(v,{}),(0,d.jsxs)("main",{children:[(0,d.jsx)(x,{}),(0,d.jsx)(y,{}),(0,d.jsx)(f,{}),(0,d.jsx)(S,{}),(0,d.jsx)(j,{}),(0,d.jsx)(N,{})]})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/ccc49370.1c88001f.js b/docs/assets/js/ccc49370.1c88001f.js new file mode 100644 index 00000000..6012d4d3 --- /dev/null +++ b/docs/assets/js/ccc49370.1c88001f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3249],{1689:(e,t,n)=>{n.d(t,{A:()=>d});n(6540);var a=n(4164),s=n(4084),i=n(7559),r=n(7293),l=n(4848);function o({className:e}){return(0,l.jsx)(r.A,{type:"caution",title:(0,l.jsx)(s.Yh,{}),className:(0,a.A)(e,i.G.common.draftBanner),children:(0,l.jsx)(s.TT,{})})}var c=n(2234);function d({metadata:e}){const{unlisted:t,frontMatter:n}=e;return(0,l.jsxs)(l.Fragment,{children:[(t||n.unlisted)&&(0,l.jsx)(c.A,{}),n.draft&&(0,l.jsx)(o,{})]})}},2053:(e,t,n)=>{n.d(t,{A:()=>o});n(6540);var a=n(4164),s=n(1312),i=n(6133);const r={tags:"tags_jXut",tag:"tag_QGVx"};var l=n(4848);function o({tags:e}){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("b",{children:(0,l.jsx)(s.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,l.jsx)("ul",{className:(0,a.A)(r.tags,"padding--none","margin-left--sm"),children:e.map(e=>(0,l.jsx)("li",{className:r.tag,children:(0,l.jsx)(i.A,{...e})},e.permalink))})]})}},2234:(e,t,n)=>{n.d(t,{A:()=>c});n(6540);var a=n(4164),s=n(7559),i=n(4084),r=n(7293),l=n(4848);function o({className:e}){return(0,l.jsx)(r.A,{type:"caution",title:(0,l.jsx)(i.Rc,{}),className:(0,a.A)(e,s.G.common.unlistedBanner),children:(0,l.jsx)(i.Uh,{})})}function c(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(i.AE,{}),(0,l.jsx)(o,{...e})]})}},2907:(e,t,n)=>{n.d(t,{A:()=>O});n(6540);var a=n(4164),s=n(4096),i=n(4848);function r({children:e,className:t}){return(0,i.jsx)("article",{className:t,children:e})}var l=n(8774);const o={title:"title_f1Hy"};function c({className:e}){const{metadata:t,isBlogPostPage:n}=(0,s.e7)(),{permalink:r,title:c}=t,d=n?"h1":"h2";return(0,i.jsx)(d,{className:(0,a.A)(o.title,e),children:n?c:(0,i.jsx)(l.A,{to:r,children:c})})}var d=n(1312),m=n(5846),u=n(6266);const g={container:"container_mt6G"};function h({readingTime:e}){const t=function(){const{selectMessage:e}=(0,m.W)();return t=>{const n=Math.ceil(t);return e(n,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:n}))}}();return(0,i.jsx)(i.Fragment,{children:t(e)})}function x({date:e,formattedDate:t}){return(0,i.jsx)("time",{dateTime:e,children:t})}function f(){return(0,i.jsx)(i.Fragment,{children:" \xb7 "})}function p({className:e}){const{metadata:t}=(0,s.e7)(),{date:n,readingTime:r}=t,l=(0,u.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,i.jsxs)("div",{className:(0,a.A)(g.container,"margin-vert--md",e),children:[(0,i.jsx)(x,{date:n,formattedDate:(o=n,l.format(new Date(o)))}),void 0!==r&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(f,{}),(0,i.jsx)(h,{readingTime:r})]})]});var o}var v=n(6382);const j={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function b({className:e}){const{metadata:{authors:t},assets:n}=(0,s.e7)();if(0===t.length)return null;const r=t.every(({name:e})=>!e),l=1===t.length;return(0,i.jsx)("div",{className:(0,a.A)("margin-top--md margin-bottom--sm",r?j.imageOnlyAuthorRow:"row",e),children:t.map((e,t)=>(0,i.jsx)("div",{className:(0,a.A)(!r&&(l?"col col--12":"col col--6"),r?j.imageOnlyAuthorCol:j.authorCol),children:(0,i.jsx)(v.A,{author:{...e,imageURL:n.authorsImageUrls[t]??e.imageURL}})},t))})}function A(){return(0,i.jsxs)("header",{children:[(0,i.jsx)(c,{}),(0,i.jsx)(p,{}),(0,i.jsx)(b,{})]})}var N=n(440),_=n(3253);function L({children:e,className:t}){const{isBlogPostPage:n}=(0,s.e7)();return(0,i.jsx)("div",{id:n?N.LU:void 0,className:(0,a.A)("markdown",t),children:(0,i.jsx)(_.A,{children:e})})}var y=n(7559),C=n(4336),T=n(2053);function k(){return(0,i.jsx)("b",{children:(0,i.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function H(e){const{blogPostTitle:t,...n}=e;return(0,i.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...n,children:(0,i.jsx)(k,{})})}function w(){const{metadata:e,isBlogPostPage:t}=(0,s.e7)(),{tags:n,title:r,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,m=!t&&o,u=n.length>0;if(!(u||m||l))return null;if(t){const e=!!(l||d||c);return(0,i.jsxs)("footer",{className:"docusaurus-mt-lg",children:[u&&(0,i.jsx)("div",{className:(0,a.A)("row","margin-top--sm",y.G.blog.blogFooterEditMetaRow),children:(0,i.jsx)("div",{className:"col",children:(0,i.jsx)(T.A,{tags:n})})}),e&&(0,i.jsx)(C.A,{className:(0,a.A)("margin-top--sm",y.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,i.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[u&&(0,i.jsx)("div",{className:(0,a.A)("col",{"col--9":m}),children:(0,i.jsx)(T.A,{tags:n})}),m&&(0,i.jsx)("div",{className:(0,a.A)("col text--right",{"col--3":u}),children:(0,i.jsx)(H,{blogPostTitle:r,to:e.permalink})})]})}function O({children:e,className:t}){const n=function(){const{isBlogPostPage:e}=(0,s.e7)();return e?void 0:"margin-bottom--xl"}();return(0,i.jsxs)(r,{className:(0,a.A)(n,t),children:[(0,i.jsx)(A,{}),(0,i.jsx)(L,{children:e}),(0,i.jsx)(w,{})]})}},3858:(e,t,n)=>{n.r(t),n.d(t,{default:()=>j});n(6540);var a=n(4164),s=n(5500),i=n(7559),r=n(4096),l=n(8027),o=n(2907),c=n(1312),d=n(9022),m=n(4848);function u(e){const{nextItem:t,prevItem:n}=e;return(0,m.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,c.T)({id:"theme.blog.post.paginator.navAriaLabel",message:"Blog post page navigation",description:"The ARIA label for the blog posts pagination"}),children:[n&&(0,m.jsx)(d.A,{...n,subLabel:(0,m.jsx)(c.A,{id:"theme.blog.post.paginator.newerPost",description:"The blog post button label to navigate to the newer/previous post",children:"Newer post"})}),t&&(0,m.jsx)(d.A,{...t,subLabel:(0,m.jsx)(c.A,{id:"theme.blog.post.paginator.olderPost",description:"The blog post button label to navigate to the older/next post",children:"Older post"}),isNext:!0})]})}function g(){const{assets:e,metadata:t}=(0,r.e7)(),{title:n,description:a,date:i,tags:l,authors:o,frontMatter:c}=t,{keywords:d}=c,u=e.image??c.image;return(0,m.jsxs)(s.be,{title:c.title_meta??n,description:a,keywords:d,image:u,children:[(0,m.jsx)("meta",{property:"og:type",content:"article"}),(0,m.jsx)("meta",{property:"article:published_time",content:i}),o.some(e=>e.url)&&(0,m.jsx)("meta",{property:"article:author",content:o.map(e=>e.url).filter(Boolean).join(",")}),l.length>0&&(0,m.jsx)("meta",{property:"article:tag",content:l.map(e=>e.label).join(",")})]})}var h=n(5260);function x(){const e=(0,r.J_)();return(0,m.jsx)(h.A,{children:(0,m.jsx)("script",{type:"application/ld+json",children:JSON.stringify(e)})})}var f=n(7763),p=n(1689);function v({sidebar:e,children:t}){const{metadata:n,toc:a}=(0,r.e7)(),{nextItem:s,prevItem:i,frontMatter:c}=n,{hide_table_of_contents:d,toc_min_heading_level:g,toc_max_heading_level:h}=c;return(0,m.jsxs)(l.A,{sidebar:e,toc:!d&&a.length>0?(0,m.jsx)(f.A,{toc:a,minHeadingLevel:g,maxHeadingLevel:h}):void 0,children:[(0,m.jsx)(p.A,{metadata:n}),(0,m.jsx)(o.A,{children:t}),(s||i)&&(0,m.jsx)(u,{nextItem:s,prevItem:i})]})}function j(e){const t=e.content;return(0,m.jsx)(r.in,{content:e.content,isBlogPostPage:!0,children:(0,m.jsxs)(s.e3,{className:(0,a.A)(i.G.wrapper.blogPages,i.G.page.blogPostPage),children:[(0,m.jsx)(g,{}),(0,m.jsx)(x,{}),(0,m.jsx)(v,{sidebar:e.sidebar,children:(0,m.jsx)(t,{})})]})})}},4084:(e,t,n)=>{n.d(t,{AE:()=>o,Rc:()=>r,TT:()=>d,Uh:()=>l,Yh:()=>c});n(6540);var a=n(1312),s=n(5260),i=n(4848);function r(){return(0,i.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,i.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function o(){return(0,i.jsx)(s.A,{children:(0,i.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,i.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,i.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}},5195:(e,t,n)=>{n.d(t,{A:()=>x});var a=n(6540),s=n(6342);function i(e){const t=e.map(e=>({...e,parentIndex:-1,children:[]})),n=Array(7).fill(-1);t.forEach((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t});const a=[];return t.forEach(e=>{const{parentIndex:n,...s}=e;n>=0?t[n].children.push(s):a.push(s)}),a}function r({toc:e,minHeadingLevel:t,maxHeadingLevel:n}){return e.flatMap(e=>{const a=r({toc:e.children,minHeadingLevel:t,maxHeadingLevel:n});return function(e){return e.level>=t&&e.level<=n}(e)?[{...e,children:a}]:a})}function l(e){const t=e.getBoundingClientRect();return t.top===t.bottom?l(e.parentNode):t}function o(e,{anchorTopOffset:t}){const n=e.find(e=>l(e).top>=t);if(n){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(l(n))?n:e[e.indexOf(n)-1]??null}return e[e.length-1]??null}function c(){const e=(0,a.useRef)(0),{navbar:{hideOnScroll:t}}=(0,s.p)();return(0,a.useEffect)(()=>{e.current=t?0:document.querySelector(".navbar").clientHeight},[t]),e}function d(e){const t=(0,a.useRef)(void 0),n=c();(0,a.useEffect)(()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:s,minHeadingLevel:i,maxHeadingLevel:r}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),l=function({minHeadingLevel:e,maxHeadingLevel:t}){const n=[];for(let a=e;a<=t;a+=1)n.push(`h${a}.anchor`);return Array.from(document.querySelectorAll(n.join()))}({minHeadingLevel:i,maxHeadingLevel:r}),c=o(l,{anchorTopOffset:n.current}),d=e.find(e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e));e.forEach(e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(s),e.classList.add(s),t.current=e):e.classList.remove(s)}(e,e===d)})}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}},[e,n])}var m=n(8774),u=n(4848);function g({toc:e,className:t,linkClassName:n,isChild:a}){return e.length?(0,u.jsx)("ul",{className:a?void 0:t,children:e.map(e=>(0,u.jsxs)("li",{children:[(0,u.jsx)(m.A,{to:`#${e.id}`,className:n??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,u.jsx)(g,{isChild:!0,toc:e.children,className:t,linkClassName:n})]},e.id))}):null}const h=a.memo(g);function x({toc:e,className:t="table-of-contents table-of-contents__left-border",linkClassName:n="table-of-contents__link",linkActiveClassName:l,minHeadingLevel:o,maxHeadingLevel:c,...m}){const g=(0,s.p)(),x=o??g.tableOfContents.minHeadingLevel,f=c??g.tableOfContents.maxHeadingLevel,p=function({toc:e,minHeadingLevel:t,maxHeadingLevel:n}){return(0,a.useMemo)(()=>r({toc:i(e),minHeadingLevel:t,maxHeadingLevel:n}),[e,t,n])}({toc:e,minHeadingLevel:x,maxHeadingLevel:f});return d((0,a.useMemo)(()=>{if(n&&l)return{linkClassName:n,linkActiveClassName:l,minHeadingLevel:x,maxHeadingLevel:f}},[n,l,x,f])),(0,u.jsx)(h,{toc:p,className:t,linkClassName:n,...m})}},6133:(e,t,n)=>{n.d(t,{A:()=>l});n(6540);var a=n(4164),s=n(8774);const i={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var r=n(4848);function l({permalink:e,label:t,count:n,description:l}){return(0,r.jsxs)(s.A,{rel:"tag",href:e,title:l,className:(0,a.A)(i.tag,n?i.tagWithCount:i.tagRegular),children:[t,n&&(0,r.jsx)("span",{children:n})]})}},7763:(e,t,n)=>{n.d(t,{A:()=>c});n(6540);var a=n(4164),s=n(5195);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var r=n(4848);const l="table-of-contents__link toc-highlight",o="table-of-contents__link--active";function c({className:e,...t}){return(0,r.jsx)("div",{className:(0,a.A)(i.tableOfContents,"thin-scrollbar",e),children:(0,r.jsx)(s.A,{...t,linkClassName:l,linkActiveClassName:o})})}},9022:(e,t,n)=>{n.d(t,{A:()=>r});n(6540);var a=n(4164),s=n(8774),i=n(4848);function r(e){const{permalink:t,title:n,subLabel:r,isNext:l}=e;return(0,i.jsxs)(s.A,{className:(0,a.A)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[r&&(0,i.jsx)("div",{className:"pagination-nav__sublabel",children:r}),(0,i.jsx)("div",{className:"pagination-nav__label",children:n})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/ccc49370.8f9e0351.js b/docs/assets/js/ccc49370.8f9e0351.js deleted file mode 100644 index 7648bd8a..00000000 --- a/docs/assets/js/ccc49370.8f9e0351.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3249],{1689:(e,t,n)=>{n.d(t,{A:()=>d});n(6540);var a=n(4164),s=n(4084),i=n(7559),r=n(7293),l=n(4848);function o({className:e}){return(0,l.jsx)(r.A,{type:"caution",title:(0,l.jsx)(s.Yh,{}),className:(0,a.A)(e,i.G.common.draftBanner),children:(0,l.jsx)(s.TT,{})})}var c=n(2234);function d({metadata:e}){const{unlisted:t,frontMatter:n}=e;return(0,l.jsxs)(l.Fragment,{children:[(t||n.unlisted)&&(0,l.jsx)(c.A,{}),n.draft&&(0,l.jsx)(o,{})]})}},2053:(e,t,n)=>{n.d(t,{A:()=>o});n(6540);var a=n(4164),s=n(1312),i=n(6133);const r={tags:"tags_jXut",tag:"tag_QGVx"};var l=n(4848);function o({tags:e}){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("b",{children:(0,l.jsx)(s.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,l.jsx)("ul",{className:(0,a.A)(r.tags,"padding--none","margin-left--sm"),children:e.map((e=>(0,l.jsx)("li",{className:r.tag,children:(0,l.jsx)(i.A,{...e})},e.permalink)))})]})}},2234:(e,t,n)=>{n.d(t,{A:()=>c});n(6540);var a=n(4164),s=n(4084),i=n(7559),r=n(7293),l=n(4848);function o({className:e}){return(0,l.jsx)(r.A,{type:"caution",title:(0,l.jsx)(s.Rc,{}),className:(0,a.A)(e,i.G.common.unlistedBanner),children:(0,l.jsx)(s.Uh,{})})}function c(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(s.AE,{}),(0,l.jsx)(o,{...e})]})}},2907:(e,t,n)=>{n.d(t,{A:()=>O});n(6540);var a=n(4164),s=n(4096),i=n(4848);function r({children:e,className:t}){return(0,i.jsx)("article",{className:t,children:e})}var l=n(8774);const o={title:"title_f1Hy"};function c({className:e}){const{metadata:t,isBlogPostPage:n}=(0,s.e7)(),{permalink:r,title:c}=t,d=n?"h1":"h2";return(0,i.jsx)(d,{className:(0,a.A)(o.title,e),children:n?c:(0,i.jsx)(l.A,{to:r,children:c})})}var d=n(1312),m=n(5846),u=n(6266);const g={container:"container_mt6G"};function h({readingTime:e}){const t=function(){const{selectMessage:e}=(0,m.W)();return t=>{const n=Math.ceil(t);return e(n,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:n}))}}();return(0,i.jsx)(i.Fragment,{children:t(e)})}function x({date:e,formattedDate:t}){return(0,i.jsx)("time",{dateTime:e,children:t})}function f(){return(0,i.jsx)(i.Fragment,{children:" \xb7 "})}function p({className:e}){const{metadata:t}=(0,s.e7)(),{date:n,readingTime:r}=t,l=(0,u.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,i.jsxs)("div",{className:(0,a.A)(g.container,"margin-vert--md",e),children:[(0,i.jsx)(x,{date:n,formattedDate:(o=n,l.format(new Date(o)))}),void 0!==r&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(f,{}),(0,i.jsx)(h,{readingTime:r})]})]});var o}var v=n(6382);const j={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function b({className:e}){const{metadata:{authors:t},assets:n}=(0,s.e7)();if(0===t.length)return null;const r=t.every((({name:e})=>!e)),l=1===t.length;return(0,i.jsx)("div",{className:(0,a.A)("margin-top--md margin-bottom--sm",r?j.imageOnlyAuthorRow:"row",e),children:t.map(((e,t)=>(0,i.jsx)("div",{className:(0,a.A)(!r&&(l?"col col--12":"col col--6"),r?j.imageOnlyAuthorCol:j.authorCol),children:(0,i.jsx)(v.A,{author:{...e,imageURL:n.authorsImageUrls[t]??e.imageURL}})},t)))})}function A(){return(0,i.jsxs)("header",{children:[(0,i.jsx)(c,{}),(0,i.jsx)(p,{}),(0,i.jsx)(b,{})]})}var N=n(440),_=n(3253);function L({children:e,className:t}){const{isBlogPostPage:n}=(0,s.e7)();return(0,i.jsx)("div",{id:n?N.LU:void 0,className:(0,a.A)("markdown",t),children:(0,i.jsx)(_.A,{children:e})})}var y=n(7559),C=n(4336),T=n(2053);function k(){return(0,i.jsx)("b",{children:(0,i.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function H(e){const{blogPostTitle:t,...n}=e;return(0,i.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...n,children:(0,i.jsx)(k,{})})}function w(){const{metadata:e,isBlogPostPage:t}=(0,s.e7)(),{tags:n,title:r,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,m=!t&&o,u=n.length>0;if(!(u||m||l))return null;if(t){const e=!!(l||d||c);return(0,i.jsxs)("footer",{className:"docusaurus-mt-lg",children:[u&&(0,i.jsx)("div",{className:(0,a.A)("row","margin-top--sm",y.G.blog.blogFooterEditMetaRow),children:(0,i.jsx)("div",{className:"col",children:(0,i.jsx)(T.A,{tags:n})})}),e&&(0,i.jsx)(C.A,{className:(0,a.A)("margin-top--sm",y.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,i.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[u&&(0,i.jsx)("div",{className:(0,a.A)("col",{"col--9":m}),children:(0,i.jsx)(T.A,{tags:n})}),m&&(0,i.jsx)("div",{className:(0,a.A)("col text--right",{"col--3":u}),children:(0,i.jsx)(H,{blogPostTitle:r,to:e.permalink})})]})}function O({children:e,className:t}){const n=function(){const{isBlogPostPage:e}=(0,s.e7)();return e?void 0:"margin-bottom--xl"}();return(0,i.jsxs)(r,{className:(0,a.A)(n,t),children:[(0,i.jsx)(A,{}),(0,i.jsx)(L,{children:e}),(0,i.jsx)(w,{})]})}},3858:(e,t,n)=>{n.r(t),n.d(t,{default:()=>j});n(6540);var a=n(4164),s=n(5500),i=n(7559),r=n(4096),l=n(8027),o=n(2907),c=n(1312),d=n(9022),m=n(4848);function u(e){const{nextItem:t,prevItem:n}=e;return(0,m.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,c.T)({id:"theme.blog.post.paginator.navAriaLabel",message:"Blog post page navigation",description:"The ARIA label for the blog posts pagination"}),children:[n&&(0,m.jsx)(d.A,{...n,subLabel:(0,m.jsx)(c.A,{id:"theme.blog.post.paginator.newerPost",description:"The blog post button label to navigate to the newer/previous post",children:"Newer post"})}),t&&(0,m.jsx)(d.A,{...t,subLabel:(0,m.jsx)(c.A,{id:"theme.blog.post.paginator.olderPost",description:"The blog post button label to navigate to the older/next post",children:"Older post"}),isNext:!0})]})}function g(){const{assets:e,metadata:t}=(0,r.e7)(),{title:n,description:a,date:i,tags:l,authors:o,frontMatter:c}=t,{keywords:d}=c,u=e.image??c.image;return(0,m.jsxs)(s.be,{title:c.title_meta??n,description:a,keywords:d,image:u,children:[(0,m.jsx)("meta",{property:"og:type",content:"article"}),(0,m.jsx)("meta",{property:"article:published_time",content:i}),o.some((e=>e.url))&&(0,m.jsx)("meta",{property:"article:author",content:o.map((e=>e.url)).filter(Boolean).join(",")}),l.length>0&&(0,m.jsx)("meta",{property:"article:tag",content:l.map((e=>e.label)).join(",")})]})}var h=n(5260);function x(){const e=(0,r.J_)();return(0,m.jsx)(h.A,{children:(0,m.jsx)("script",{type:"application/ld+json",children:JSON.stringify(e)})})}var f=n(7763),p=n(1689);function v({sidebar:e,children:t}){const{metadata:n,toc:a}=(0,r.e7)(),{nextItem:s,prevItem:i,frontMatter:c}=n,{hide_table_of_contents:d,toc_min_heading_level:g,toc_max_heading_level:h}=c;return(0,m.jsxs)(l.A,{sidebar:e,toc:!d&&a.length>0?(0,m.jsx)(f.A,{toc:a,minHeadingLevel:g,maxHeadingLevel:h}):void 0,children:[(0,m.jsx)(p.A,{metadata:n}),(0,m.jsx)(o.A,{children:t}),(s||i)&&(0,m.jsx)(u,{nextItem:s,prevItem:i})]})}function j(e){const t=e.content;return(0,m.jsx)(r.in,{content:e.content,isBlogPostPage:!0,children:(0,m.jsxs)(s.e3,{className:(0,a.A)(i.G.wrapper.blogPages,i.G.page.blogPostPage),children:[(0,m.jsx)(g,{}),(0,m.jsx)(x,{}),(0,m.jsx)(v,{sidebar:e.sidebar,children:(0,m.jsx)(t,{})})]})})}},4084:(e,t,n)=>{n.d(t,{AE:()=>o,Rc:()=>r,TT:()=>d,Uh:()=>l,Yh:()=>c});n(6540);var a=n(1312),s=n(5260),i=n(4848);function r(){return(0,i.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,i.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function o(){return(0,i.jsx)(s.A,{children:(0,i.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,i.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,i.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}},5195:(e,t,n)=>{n.d(t,{A:()=>x});var a=n(6540),s=n(6342);function i(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...s}=e;n>=0?t[n].children.push(s):a.push(s)})),a}function r({toc:e,minHeadingLevel:t,maxHeadingLevel:n}){return e.flatMap((e=>{const a=r({toc:e.children,minHeadingLevel:t,maxHeadingLevel:n});return function(e){return e.level>=t&&e.level<=n}(e)?[{...e,children:a}]:a}))}function l(e){const t=e.getBoundingClientRect();return t.top===t.bottom?l(e.parentNode):t}function o(e,{anchorTopOffset:t}){const n=e.find((e=>l(e).top>=t));if(n){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(l(n))?n:e[e.indexOf(n)-1]??null}return e[e.length-1]??null}function c(){const e=(0,a.useRef)(0),{navbar:{hideOnScroll:t}}=(0,s.p)();return(0,a.useEffect)((()=>{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,a.useRef)(void 0),n=c();(0,a.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:s,minHeadingLevel:i,maxHeadingLevel:r}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),l=function({minHeadingLevel:e,maxHeadingLevel:t}){const n=[];for(let a=e;a<=t;a+=1)n.push(`h${a}.anchor`);return Array.from(document.querySelectorAll(n.join()))}({minHeadingLevel:i,maxHeadingLevel:r}),c=o(l,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(s),e.classList.add(s),t.current=e):e.classList.remove(s)}(e,e===d)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,n])}var m=n(8774),u=n(4848);function g({toc:e,className:t,linkClassName:n,isChild:a}){return e.length?(0,u.jsx)("ul",{className:a?void 0:t,children:e.map((e=>(0,u.jsxs)("li",{children:[(0,u.jsx)(m.A,{to:`#${e.id}`,className:n??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,u.jsx)(g,{isChild:!0,toc:e.children,className:t,linkClassName:n})]},e.id)))}):null}const h=a.memo(g);function x({toc:e,className:t="table-of-contents table-of-contents__left-border",linkClassName:n="table-of-contents__link",linkActiveClassName:l,minHeadingLevel:o,maxHeadingLevel:c,...m}){const g=(0,s.p)(),x=o??g.tableOfContents.minHeadingLevel,f=c??g.tableOfContents.maxHeadingLevel,p=function({toc:e,minHeadingLevel:t,maxHeadingLevel:n}){return(0,a.useMemo)((()=>r({toc:i(e),minHeadingLevel:t,maxHeadingLevel:n})),[e,t,n])}({toc:e,minHeadingLevel:x,maxHeadingLevel:f});return d((0,a.useMemo)((()=>{if(n&&l)return{linkClassName:n,linkActiveClassName:l,minHeadingLevel:x,maxHeadingLevel:f}}),[n,l,x,f])),(0,u.jsx)(h,{toc:p,className:t,linkClassName:n,...m})}},6133:(e,t,n)=>{n.d(t,{A:()=>l});n(6540);var a=n(4164),s=n(8774);const i={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var r=n(4848);function l({permalink:e,label:t,count:n,description:l}){return(0,r.jsxs)(s.A,{rel:"tag",href:e,title:l,className:(0,a.A)(i.tag,n?i.tagWithCount:i.tagRegular),children:[t,n&&(0,r.jsx)("span",{children:n})]})}},7763:(e,t,n)=>{n.d(t,{A:()=>c});n(6540);var a=n(4164),s=n(5195);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var r=n(4848);const l="table-of-contents__link toc-highlight",o="table-of-contents__link--active";function c({className:e,...t}){return(0,r.jsx)("div",{className:(0,a.A)(i.tableOfContents,"thin-scrollbar",e),children:(0,r.jsx)(s.A,{...t,linkClassName:l,linkActiveClassName:o})})}},9022:(e,t,n)=>{n.d(t,{A:()=>r});n(6540);var a=n(4164),s=n(8774),i=n(4848);function r(e){const{permalink:t,title:n,subLabel:r,isNext:l}=e;return(0,i.jsxs)(s.A,{className:(0,a.A)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[r&&(0,i.jsx)("div",{className:"pagination-nav__sublabel",children:r}),(0,i.jsx)("div",{className:"pagination-nav__label",children:n})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/d152284c.0800e671.js b/docs/assets/js/d152284c.0800e671.js new file mode 100644 index 00000000..ff655ac8 --- /dev/null +++ b/docs/assets/js/d152284c.0800e671.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1606],{5876:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"online-feature-store/v1.0.0/release-notes","title":"Release Notes","description":"Version 1.0.0 \ud83d\ude80","source":"@site/docs/online-feature-store/v1.0.0/release-notes.md","sourceDirName":"online-feature-store/v1.0.0","slug":"/online-feature-store/v1.0.0/release-notes","permalink":"/BharatMLStack/online-feature-store/v1.0.0/release-notes","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/online-feature-store/v1.0.0/release-notes.md","tags":[],"version":"current","sidebarPosition":5,"frontMatter":{"title":"Release Notes","sidebar_position":5},"sidebar":"tutorialSidebar","previous":{"title":"Key Functionalities","permalink":"/BharatMLStack/online-feature-store/v1.0.0/functionalities"},"next":{"title":"Inferflow","permalink":"/BharatMLStack/category/inferflow"}}');var i=r(4848),t=r(8453);const l={title:"Release Notes",sidebar_position:5},o="Online Feature Store - Release Notes",a={},c=[{value:"Version 1.0.0 \ud83d\ude80",id:"version-100-",level:2},{value:"\ud83c\udfaf <strong>What's New</strong>",id:"-whats-new",level:2},{value:"<strong>Core Feature Store Engine</strong>",id:"core-feature-store-engine",level:3},{value:"<strong>Advanced Data Type Support</strong>",id:"advanced-data-type-support",level:3},{value:"<strong>Multi-Database Architecture</strong>",id:"multi-database-architecture",level:3},{value:"\ud83d\ude80 <strong>Performance & Optimization</strong>",id:"-performance--optimization",level:2},{value:"<strong>PSDB v2 Serialization Format without compression</strong>",id:"psdb-v2-serialization-format-without-compression",level:3},{value:"<strong>Memory Management</strong>",id:"memory-management",level:3},{value:"<strong>Compression Support</strong>",id:"compression-support",level:3},{value:"\ud83d\udee0\ufe0f <strong>APIs & SDKs</strong>",id:"\ufe0f-apis--sdks",level:2},{value:"<strong>gRPC API</strong>",id:"grpc-api",level:3},{value:"<strong>Go SDK v1.0.0</strong>",id:"go-sdk-v100",level:3},{value:"<strong>Python SDK Collection v1.0.0</strong>",id:"python-sdk-collection-v100",level:3},{value:"<strong>RESTful Interface</strong>",id:"restful-interface",level:3},{value:"\ud83d\udd27 <strong>Enterprise Features</strong>",id:"-enterprise-features",level:2},{value:"<strong>Production Readiness</strong>",id:"production-readiness",level:3},{value:"<strong>Monitoring & Observability</strong>",id:"monitoring--observability",level:3},{value:"<strong>Data Management</strong>",id:"data-management",level:3},{value:"\ud83c\udfd7\ufe0f <strong>Deployment & Configuration</strong>",id:"\ufe0f-deployment--configuration",level:2},{value:"<strong>Container Support</strong>",id:"container-support",level:3},{value:"\ud83d\udd04 <strong>Compatibility</strong>",id:"-compatibility",level:2},{value:"<strong>Supported Go Versions</strong>",id:"supported-go-versions",level:3},{value:"<strong>Database Compatibility</strong>",id:"database-compatibility",level:3},{value:"\ud83d\udc1b <strong>Known Issues</strong>",id:"-known-issues",level:2},{value:"<strong>Current Limitations</strong>",id:"current-limitations",level:3},{value:"<strong>Workarounds</strong>",id:"workarounds",level:3},{value:"\ud83d\udcbe <strong>Download & Installation</strong>",id:"-download--installation",level:2},{value:"<strong>Container Images</strong>",id:"container-images",level:3},{value:"<strong>Arch Supported</strong>",id:"arch-supported",level:3},{value:"<strong>Source Code</strong>",id:"source-code",level:3},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"online-feature-store---release-notes",children:"Online Feature Store - Release Notes"})}),"\n",(0,i.jsx)(n.h2,{id:"version-100-",children:"Version 1.0.0 \ud83d\ude80"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Release Date"}),": June 2025",(0,i.jsx)(n.br,{}),"\n",(0,i.jsx)(n.strong,{children:"Status"}),": General Availability (GA)"]}),"\n",(0,i.jsxs)(n.p,{children:["We're excited to announce the first stable release of the ",(0,i.jsx)(n.strong,{children:"BharatML Online Feature Store"})," - a high-performance, production-ready feature serving system designed for machine learning workloads."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsxs)(n.h2,{id:"-whats-new",children:["\ud83c\udfaf ",(0,i.jsx)(n.strong,{children:"What's New"})]}),"\n",(0,i.jsx)(n.h3,{id:"core-feature-store-engine",children:(0,i.jsx)(n.strong,{children:"Core Feature Store Engine"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Ultra-Low Latency"}),": Achieve sub-10ms P99 response times for real-time inference"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"High Throughput"}),": Tested and validated at 1M+ requests per second with 100 IDs per request"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Multi-Entity Support"}),": Serve features for multiple entity types (users, transactions, products, etc.)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Batch Retrieval"}),": Efficient bulk feature fetching for real-time inference and incremental/online training workloads"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"advanced-data-type-support",children:(0,i.jsx)(n.strong,{children:"Advanced Data Type Support"})}),"\n",(0,i.jsx)(n.p,{children:"Complete support for all ML-relevant data types:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Data Type"}),(0,i.jsx)(n.th,{children:"Variants"}),(0,i.jsx)(n.th,{children:"Optimizations"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"Integers"})}),(0,i.jsx)(n.td,{children:"int8, int16, int32, int64"}),(0,i.jsx)(n.td,{children:"Varint encoding, bit packing"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"Floats"})}),(0,i.jsx)(n.td,{children:"float8, float16, float32, float64"}),(0,i.jsx)(n.td,{children:"IEEE 754 compliant storage"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"Strings"})}),(0,i.jsx)(n.td,{children:"Variable length"}),(0,i.jsx)(n.td,{children:"Pascal string encoding"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"Booleans"})}),(0,i.jsx)(n.td,{children:"Bit-packed"}),(0,i.jsx)(n.td,{children:"8x memory compression"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"Vectors"})}),(0,i.jsx)(n.td,{children:"All above types"}),(0,i.jsx)(n.td,{children:"Contiguous memory layout"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"multi-database-architecture",children:(0,i.jsx)(n.strong,{children:"Multi-Database Architecture"})}),"\n",(0,i.jsx)(n.p,{children:"Flexible backend storage with optimized drivers:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"\ud83d\udd25 Scylla DB"}),": Ultra-high performance NoSQL (recommended for production)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"\u26a1 Dragonfly"}),": Modern Redis alternative with better memory efficiency"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"\ud83d\udcca Redis"}),": Standard in-memory store for development environments"]}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"-performance--optimization",children:["\ud83d\ude80 ",(0,i.jsx)(n.strong,{children:"Performance & Optimization"})]}),"\n",(0,i.jsx)(n.h3,{id:"psdb-v2-serialization-format-without-compression",children:(0,i.jsx)(n.strong,{children:"PSDB v2 Serialization Format without compression"})}),"\n",(0,i.jsxs)(n.p,{children:["Our proprietary ",(0,i.jsx)(n.strong,{children:"Permanent Storage Data Block"})," format delivers:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"35% faster"})," serialization than Protocol Buffers"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"100.0-102.2%"})," size efficiency (near raw data size)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"93% fewer allocations"})," than Apache Arrow (4 vs 66 allocs/op)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"975 MB/s"})," throughput capacity"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"memory-management",children:(0,i.jsx)(n.strong,{children:"Memory Management"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Object Pooling"}),": Zero-allocation feature retrieval with PSDBPool"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Connection Pooling"}),": Optimized database connection reuse"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Buffer Management"}),": Pre-allocated buffers for serialization operations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Smart Caching"}),": Configurable TTL-based feature caching"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"compression-support",children:(0,i.jsx)(n.strong,{children:"Compression Support"})}),"\n",(0,i.jsx)(n.p,{children:"Intelligent compression with multiple algorithms:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"ZSTD"}),": Maximum compression for bandwidth-constrained environments"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Auto-Fallback"}),": Intelligent selection based on data characteristics"]}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"\ufe0f-apis--sdks",children:["\ud83d\udee0\ufe0f ",(0,i.jsx)(n.strong,{children:"APIs & SDKs"})]}),"\n",(0,i.jsx)(n.h3,{id:"grpc-api",children:(0,i.jsx)(n.strong,{children:"gRPC API"})}),"\n",(0,i.jsx)(n.p,{children:"High-performance, language-agnostic interface:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-protobuf",children:"service FeatureStoreService {\n rpc RetrieveFeatures(Query) returns (QueryResult);\n rpc RetrieveDecodedFeatures(Query) returns (DecodedQueryResult);\n rpc PersistFeatures(PersistFeaturesRequest) returns (Result);\n}\n"})}),"\n",(0,i.jsx)(n.h3,{id:"go-sdk-v100",children:(0,i.jsx)(n.strong,{children:"Go SDK v1.0.0"})}),"\n",(0,i.jsx)(n.p,{children:"Native Go client with enterprise features:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Type-Safe API"}),": Strongly typed interfaces and data structures"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Connection Management"}),": Configurable timeouts, TLS, and pooling"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Batch Processing"}),": Configurable batch sizes for bulk operations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Metrics Integration"}),": Built-in timing and count metrics"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Authentication"}),": Caller ID and token-based security"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"python-sdk-collection-v100",children:(0,i.jsx)(n.strong,{children:"Python SDK Collection v1.0.0"})}),"\n",(0,i.jsx)(n.p,{children:"Three specialized Python packages for different ML workflows:"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"bharatml_commons"})," - Common utilities and protobuf definitions:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"HTTP Client"}),": Feature metadata operations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Protobuf Support"}),": Generated Python definitions for all APIs"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Utility Functions"}),": Column cleaning and feature processing"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"spark_feature_push_client"})," - Apache Spark-based data pipeline:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Batch ETL"}),": Large-scale data processing with Spark"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Kafka Integration"}),": Protobuf serialization and Kafka publishing"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Multi-Source Support"}),": Hive, Delta, Parquet, Cloud Storage"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"grpc_feature_client"})," - High-performance gRPC client:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Real-time Operations"}),": Direct persist/retrieve API access"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Low Latency"}),": Optimized for model inference workflows"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Type Safety"}),": Strongly typed Python interfaces"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"restful-interface",children:(0,i.jsx)(n.strong,{children:"RESTful Interface"})}),"\n",(0,i.jsx)(n.p,{children:"HTTP API for web applications:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Health Endpoints"}),": Built-in monitoring and status checks"]}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"-enterprise-features",children:["\ud83d\udd27 ",(0,i.jsx)(n.strong,{children:"Enterprise Features"})]}),"\n",(0,i.jsx)(n.h3,{id:"production-readiness",children:(0,i.jsx)(n.strong,{children:"Production Readiness"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Health Checks"}),": ",(0,i.jsx)(n.code,{children:"/health/self"})," endpoints for probing"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Graceful Shutdown"}),": Clean resource cleanup with configurable timeouts"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Structured Logging"}),": Formatted logs with configurable levels"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Signal Handling"}),": SIGTERM/SIGINT support for container environments"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"monitoring--observability",children:(0,i.jsx)(n.strong,{children:"Monitoring & Observability"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"DataDog Integration"}),": Built-in metrics collection and reporting"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Prometheus Compatibility"}),": Standard metrics format support"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Custom Metrics"}),": Request rates, latencies, error rates, and business metrics"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Distributed Tracing [untested]"}),": Request flow visibility across services"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"data-management",children:(0,i.jsx)(n.strong,{children:"Data Management"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"TTL Support"}),": Automatic feature expiration"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Feature Versioning"}),": Schema evolution with backward compatibility"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Bulk Operations"}),": Efficient batch read/write with configurable sizes"]}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"\ufe0f-deployment--configuration",children:["\ud83c\udfd7\ufe0f ",(0,i.jsx)(n.strong,{children:"Deployment & Configuration"})]}),"\n",(0,i.jsx)(n.h3,{id:"container-support",children:(0,i.jsx)(n.strong,{children:"Container Support"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Docker Images"}),": Multi-architecture support (amd64, arm64)"]}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"-compatibility",children:["\ud83d\udd04 ",(0,i.jsx)(n.strong,{children:"Compatibility"})]}),"\n",(0,i.jsx)(n.h3,{id:"supported-go-versions",children:(0,i.jsx)(n.strong,{children:"Supported Go Versions"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Minimum"}),": Go 1.22.0"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Recommended"}),": Go 1.22.8+"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"database-compatibility",children:(0,i.jsx)(n.strong,{children:"Database Compatibility"})}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Database"}),(0,i.jsx)(n.th,{children:"Version"}),(0,i.jsx)(n.th,{children:"Status"}),(0,i.jsx)(n.th,{children:"Notes"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Scylla DB"}),(0,i.jsx)(n.td,{children:"5.0+"}),(0,i.jsx)(n.td,{children:"\u2705 Recommended"}),(0,i.jsx)(n.td,{children:"Optimal performance"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Dragonfly"}),(0,i.jsx)(n.td,{children:"1.0+"}),(0,i.jsx)(n.td,{children:"\u2705 Supported"}),(0,i.jsx)(n.td,{children:"Memory efficient"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Redis"}),(0,i.jsx)(n.td,{children:"6.0+"}),(0,i.jsx)(n.td,{children:"\u2705 Development"}),(0,i.jsx)(n.td,{children:"Limited scale"})]})]})]}),"\n",(0,i.jsxs)(n.h2,{id:"-known-issues",children:["\ud83d\udc1b ",(0,i.jsx)(n.strong,{children:"Known Issues"})]}),"\n",(0,i.jsx)(n.h3,{id:"current-limitations",children:(0,i.jsx)(n.strong,{children:"Current Limitations"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Large Vector Support"}),": Vectors >10MB may experience increased latency"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"workarounds",children:(0,i.jsx)(n.strong,{children:"Workarounds"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Vector Chunking"}),": Split large vectors into smaller segments"]}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"-download--installation",children:["\ud83d\udcbe ",(0,i.jsx)(n.strong,{children:"Download & Installation"})]}),"\n",(0,i.jsx)(n.h3,{id:"container-images",children:(0,i.jsx)(n.strong,{children:"Container Images"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Pull the latest image\ndocker pull ghcr.io/meesho/onfs-api-server:latest\ndocker pull ghcr.io/meesho/onfs-consumer:latest\ndocker pull ghcr.io/meesho/horizon:latest\ndocker pull ghcr.io/meesho/trufflebox-ui:latest\n\n"})}),"\n",(0,i.jsx)(n.h3,{id:"arch-supported",children:(0,i.jsx)(n.strong,{children:"Arch Supported"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.strong,{children:"Linux (amd64)"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.strong,{children:"Linux (arm64)"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.strong,{children:"macOS (Intel)"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.strong,{children:"macOS (Apple Silicon)"})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Checkout ",(0,i.jsx)(n.a,{href:"https://github.com/orgs/Meesho/packages?repo_name=BharatMLStack",children:"Packages"})]}),"\n",(0,i.jsx)(n.h3,{id:"source-code",children:(0,i.jsx)(n.strong,{children:"Source Code"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/Meesho/BharatMLStack.git\ncd BharatMLStack/online-feature-store\ngit checkout release/1.0.0\n"})}),"\n",(0,i.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,i.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,i.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\ud83d\udcac ",(0,i.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,i.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,i.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,i.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,i.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,r)=>{r.d(n,{R:()=>l,x:()=>o});var s=r(6540);const i={},t=s.createContext(i);function l(e){const n=s.useContext(t);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/d152284c.8adb699d.js b/docs/assets/js/d152284c.8adb699d.js deleted file mode 100644 index b8f92b00..00000000 --- a/docs/assets/js/d152284c.8adb699d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1606],{5876:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"online-feature-store/v1.0.0/release-notes","title":"Release Notes","description":"Version 1.0.0 \ud83d\ude80","source":"@site/docs/online-feature-store/v1.0.0/release-notes.md","sourceDirName":"online-feature-store/v1.0.0","slug":"/online-feature-store/v1.0.0/release-notes","permalink":"/BharatMLStack/online-feature-store/v1.0.0/release-notes","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/online-feature-store/v1.0.0/release-notes.md","tags":[],"version":"current","sidebarPosition":5,"frontMatter":{"title":"Release Notes","sidebar_position":5},"sidebar":"tutorialSidebar","previous":{"title":"Key Functionalities","permalink":"/BharatMLStack/online-feature-store/v1.0.0/functionalities"},"next":{"title":"Quick Start","permalink":"/BharatMLStack/category/quick-start"}}');var i=r(4848),t=r(8453);const l={title:"Release Notes",sidebar_position:5},o="Online Feature Store - Release Notes",a={},c=[{value:"Version 1.0.0 \ud83d\ude80",id:"version-100-",level:2},{value:"\ud83c\udfaf <strong>What's New</strong>",id:"-whats-new",level:2},{value:"<strong>Core Feature Store Engine</strong>",id:"core-feature-store-engine",level:3},{value:"<strong>Advanced Data Type Support</strong>",id:"advanced-data-type-support",level:3},{value:"<strong>Multi-Database Architecture</strong>",id:"multi-database-architecture",level:3},{value:"\ud83d\ude80 <strong>Performance & Optimization</strong>",id:"-performance--optimization",level:2},{value:"<strong>PSDB v2 Serialization Format without compression</strong>",id:"psdb-v2-serialization-format-without-compression",level:3},{value:"<strong>Memory Management</strong>",id:"memory-management",level:3},{value:"<strong>Compression Support</strong>",id:"compression-support",level:3},{value:"\ud83d\udee0\ufe0f <strong>APIs & SDKs</strong>",id:"\ufe0f-apis--sdks",level:2},{value:"<strong>gRPC API</strong>",id:"grpc-api",level:3},{value:"<strong>Go SDK v1.0.0</strong>",id:"go-sdk-v100",level:3},{value:"<strong>Python SDK Collection v1.0.0</strong>",id:"python-sdk-collection-v100",level:3},{value:"<strong>RESTful Interface</strong>",id:"restful-interface",level:3},{value:"\ud83d\udd27 <strong>Enterprise Features</strong>",id:"-enterprise-features",level:2},{value:"<strong>Production Readiness</strong>",id:"production-readiness",level:3},{value:"<strong>Monitoring & Observability</strong>",id:"monitoring--observability",level:3},{value:"<strong>Data Management</strong>",id:"data-management",level:3},{value:"\ud83c\udfd7\ufe0f <strong>Deployment & Configuration</strong>",id:"\ufe0f-deployment--configuration",level:2},{value:"<strong>Container Support</strong>",id:"container-support",level:3},{value:"\ud83d\udd04 <strong>Compatibility</strong>",id:"-compatibility",level:2},{value:"<strong>Supported Go Versions</strong>",id:"supported-go-versions",level:3},{value:"<strong>Database Compatibility</strong>",id:"database-compatibility",level:3},{value:"\ud83d\udc1b <strong>Known Issues</strong>",id:"-known-issues",level:2},{value:"<strong>Current Limitations</strong>",id:"current-limitations",level:3},{value:"<strong>Workarounds</strong>",id:"workarounds",level:3},{value:"\ud83d\udcbe <strong>Download & Installation</strong>",id:"-download--installation",level:2},{value:"<strong>Container Images</strong>",id:"container-images",level:3},{value:"<strong>Arch Supported</strong>",id:"arch-supported",level:3},{value:"<strong>Source Code</strong>",id:"source-code",level:3},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"online-feature-store---release-notes",children:"Online Feature Store - Release Notes"})}),"\n",(0,i.jsx)(n.h2,{id:"version-100-",children:"Version 1.0.0 \ud83d\ude80"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Release Date"}),": June 2025",(0,i.jsx)(n.br,{}),"\n",(0,i.jsx)(n.strong,{children:"Status"}),": General Availability (GA)"]}),"\n",(0,i.jsxs)(n.p,{children:["We're excited to announce the first stable release of the ",(0,i.jsx)(n.strong,{children:"BharatML Online Feature Store"})," - a high-performance, production-ready feature serving system designed for machine learning workloads."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsxs)(n.h2,{id:"-whats-new",children:["\ud83c\udfaf ",(0,i.jsx)(n.strong,{children:"What's New"})]}),"\n",(0,i.jsx)(n.h3,{id:"core-feature-store-engine",children:(0,i.jsx)(n.strong,{children:"Core Feature Store Engine"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Ultra-Low Latency"}),": Achieve sub-10ms P99 response times for real-time inference"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"High Throughput"}),": Tested and validated at 1M+ requests per second with 100 IDs per request"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Multi-Entity Support"}),": Serve features for multiple entity types (users, transactions, products, etc.)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Batch Retrieval"}),": Efficient bulk feature fetching for real-time inference and incremental/online training workloads"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"advanced-data-type-support",children:(0,i.jsx)(n.strong,{children:"Advanced Data Type Support"})}),"\n",(0,i.jsx)(n.p,{children:"Complete support for all ML-relevant data types:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Data Type"}),(0,i.jsx)(n.th,{children:"Variants"}),(0,i.jsx)(n.th,{children:"Optimizations"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"Integers"})}),(0,i.jsx)(n.td,{children:"int8, int16, int32, int64"}),(0,i.jsx)(n.td,{children:"Varint encoding, bit packing"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"Floats"})}),(0,i.jsx)(n.td,{children:"float8, float16, float32, float64"}),(0,i.jsx)(n.td,{children:"IEEE 754 compliant storage"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"Strings"})}),(0,i.jsx)(n.td,{children:"Variable length"}),(0,i.jsx)(n.td,{children:"Pascal string encoding"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"Booleans"})}),(0,i.jsx)(n.td,{children:"Bit-packed"}),(0,i.jsx)(n.td,{children:"8x memory compression"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"Vectors"})}),(0,i.jsx)(n.td,{children:"All above types"}),(0,i.jsx)(n.td,{children:"Contiguous memory layout"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"multi-database-architecture",children:(0,i.jsx)(n.strong,{children:"Multi-Database Architecture"})}),"\n",(0,i.jsx)(n.p,{children:"Flexible backend storage with optimized drivers:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"\ud83d\udd25 Scylla DB"}),": Ultra-high performance NoSQL (recommended for production)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"\u26a1 Dragonfly"}),": Modern Redis alternative with better memory efficiency"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"\ud83d\udcca Redis"}),": Standard in-memory store for development environments"]}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"-performance--optimization",children:["\ud83d\ude80 ",(0,i.jsx)(n.strong,{children:"Performance & Optimization"})]}),"\n",(0,i.jsx)(n.h3,{id:"psdb-v2-serialization-format-without-compression",children:(0,i.jsx)(n.strong,{children:"PSDB v2 Serialization Format without compression"})}),"\n",(0,i.jsxs)(n.p,{children:["Our proprietary ",(0,i.jsx)(n.strong,{children:"Permanent Storage Data Block"})," format delivers:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"35% faster"})," serialization than Protocol Buffers"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"100.0-102.2%"})," size efficiency (near raw data size)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"93% fewer allocations"})," than Apache Arrow (4 vs 66 allocs/op)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"975 MB/s"})," throughput capacity"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"memory-management",children:(0,i.jsx)(n.strong,{children:"Memory Management"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Object Pooling"}),": Zero-allocation feature retrieval with PSDBPool"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Connection Pooling"}),": Optimized database connection reuse"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Buffer Management"}),": Pre-allocated buffers for serialization operations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Smart Caching"}),": Configurable TTL-based feature caching"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"compression-support",children:(0,i.jsx)(n.strong,{children:"Compression Support"})}),"\n",(0,i.jsx)(n.p,{children:"Intelligent compression with multiple algorithms:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"ZSTD"}),": Maximum compression for bandwidth-constrained environments"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Auto-Fallback"}),": Intelligent selection based on data characteristics"]}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"\ufe0f-apis--sdks",children:["\ud83d\udee0\ufe0f ",(0,i.jsx)(n.strong,{children:"APIs & SDKs"})]}),"\n",(0,i.jsx)(n.h3,{id:"grpc-api",children:(0,i.jsx)(n.strong,{children:"gRPC API"})}),"\n",(0,i.jsx)(n.p,{children:"High-performance, language-agnostic interface:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-protobuf",children:"service FeatureStoreService {\n rpc RetrieveFeatures(Query) returns (QueryResult);\n rpc RetrieveDecodedFeatures(Query) returns (DecodedQueryResult);\n rpc PersistFeatures(PersistFeaturesRequest) returns (Result);\n}\n"})}),"\n",(0,i.jsx)(n.h3,{id:"go-sdk-v100",children:(0,i.jsx)(n.strong,{children:"Go SDK v1.0.0"})}),"\n",(0,i.jsx)(n.p,{children:"Native Go client with enterprise features:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Type-Safe API"}),": Strongly typed interfaces and data structures"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Connection Management"}),": Configurable timeouts, TLS, and pooling"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Batch Processing"}),": Configurable batch sizes for bulk operations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Metrics Integration"}),": Built-in timing and count metrics"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Authentication"}),": Caller ID and token-based security"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"python-sdk-collection-v100",children:(0,i.jsx)(n.strong,{children:"Python SDK Collection v1.0.0"})}),"\n",(0,i.jsx)(n.p,{children:"Three specialized Python packages for different ML workflows:"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"bharatml_commons"})," - Common utilities and protobuf definitions:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"HTTP Client"}),": Feature metadata operations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Protobuf Support"}),": Generated Python definitions for all APIs"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Utility Functions"}),": Column cleaning and feature processing"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"spark_feature_push_client"})," - Apache Spark-based data pipeline:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Batch ETL"}),": Large-scale data processing with Spark"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Kafka Integration"}),": Protobuf serialization and Kafka publishing"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Multi-Source Support"}),": Hive, Delta, Parquet, Cloud Storage"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"grpc_feature_client"})," - High-performance gRPC client:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Real-time Operations"}),": Direct persist/retrieve API access"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Low Latency"}),": Optimized for model inference workflows"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Type Safety"}),": Strongly typed Python interfaces"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"restful-interface",children:(0,i.jsx)(n.strong,{children:"RESTful Interface"})}),"\n",(0,i.jsx)(n.p,{children:"HTTP API for web applications:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Health Endpoints"}),": Built-in monitoring and status checks"]}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"-enterprise-features",children:["\ud83d\udd27 ",(0,i.jsx)(n.strong,{children:"Enterprise Features"})]}),"\n",(0,i.jsx)(n.h3,{id:"production-readiness",children:(0,i.jsx)(n.strong,{children:"Production Readiness"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Health Checks"}),": ",(0,i.jsx)(n.code,{children:"/health/self"})," endpoints for probing"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Graceful Shutdown"}),": Clean resource cleanup with configurable timeouts"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Structured Logging"}),": Formatted logs with configurable levels"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Signal Handling"}),": SIGTERM/SIGINT support for container environments"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"monitoring--observability",children:(0,i.jsx)(n.strong,{children:"Monitoring & Observability"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"DataDog Integration"}),": Built-in metrics collection and reporting"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Prometheus Compatibility"}),": Standard metrics format support"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Custom Metrics"}),": Request rates, latencies, error rates, and business metrics"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Distributed Tracing [untested]"}),": Request flow visibility across services"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"data-management",children:(0,i.jsx)(n.strong,{children:"Data Management"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"TTL Support"}),": Automatic feature expiration"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Feature Versioning"}),": Schema evolution with backward compatibility"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Bulk Operations"}),": Efficient batch read/write with configurable sizes"]}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"\ufe0f-deployment--configuration",children:["\ud83c\udfd7\ufe0f ",(0,i.jsx)(n.strong,{children:"Deployment & Configuration"})]}),"\n",(0,i.jsx)(n.h3,{id:"container-support",children:(0,i.jsx)(n.strong,{children:"Container Support"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Docker Images"}),": Multi-architecture support (amd64, arm64)"]}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"-compatibility",children:["\ud83d\udd04 ",(0,i.jsx)(n.strong,{children:"Compatibility"})]}),"\n",(0,i.jsx)(n.h3,{id:"supported-go-versions",children:(0,i.jsx)(n.strong,{children:"Supported Go Versions"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Minimum"}),": Go 1.22.0"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Recommended"}),": Go 1.22.8+"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"database-compatibility",children:(0,i.jsx)(n.strong,{children:"Database Compatibility"})}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Database"}),(0,i.jsx)(n.th,{children:"Version"}),(0,i.jsx)(n.th,{children:"Status"}),(0,i.jsx)(n.th,{children:"Notes"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Scylla DB"}),(0,i.jsx)(n.td,{children:"5.0+"}),(0,i.jsx)(n.td,{children:"\u2705 Recommended"}),(0,i.jsx)(n.td,{children:"Optimal performance"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Dragonfly"}),(0,i.jsx)(n.td,{children:"1.0+"}),(0,i.jsx)(n.td,{children:"\u2705 Supported"}),(0,i.jsx)(n.td,{children:"Memory efficient"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Redis"}),(0,i.jsx)(n.td,{children:"6.0+"}),(0,i.jsx)(n.td,{children:"\u2705 Development"}),(0,i.jsx)(n.td,{children:"Limited scale"})]})]})]}),"\n",(0,i.jsxs)(n.h2,{id:"-known-issues",children:["\ud83d\udc1b ",(0,i.jsx)(n.strong,{children:"Known Issues"})]}),"\n",(0,i.jsx)(n.h3,{id:"current-limitations",children:(0,i.jsx)(n.strong,{children:"Current Limitations"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Large Vector Support"}),": Vectors >10MB may experience increased latency"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"workarounds",children:(0,i.jsx)(n.strong,{children:"Workarounds"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Vector Chunking"}),": Split large vectors into smaller segments"]}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"-download--installation",children:["\ud83d\udcbe ",(0,i.jsx)(n.strong,{children:"Download & Installation"})]}),"\n",(0,i.jsx)(n.h3,{id:"container-images",children:(0,i.jsx)(n.strong,{children:"Container Images"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Pull the latest image\ndocker pull ghcr.io/meesho/onfs-api-server:latest\ndocker pull ghcr.io/meesho/onfs-consumer:latest\ndocker pull ghcr.io/meesho/horizon:latest\ndocker pull ghcr.io/meesho/trufflebox-ui:latest\n\n"})}),"\n",(0,i.jsx)(n.h3,{id:"arch-supported",children:(0,i.jsx)(n.strong,{children:"Arch Supported"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.strong,{children:"Linux (amd64)"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.strong,{children:"Linux (arm64)"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.strong,{children:"macOS (Intel)"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.strong,{children:"macOS (Apple Silicon)"})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Checkout ",(0,i.jsx)(n.a,{href:"https://github.com/orgs/Meesho/packages?repo_name=BharatMLStack",children:"Packages"})]}),"\n",(0,i.jsx)(n.h3,{id:"source-code",children:(0,i.jsx)(n.strong,{children:"Source Code"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/Meesho/BharatMLStack.git\ncd BharatMLStack/online-feature-store\ngit checkout release/1.0.0\n"})}),"\n",(0,i.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,i.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,i.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\ud83d\udcac ",(0,i.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,i.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,i.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,i.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,i.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,i.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,i.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,i.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,i.jsx)("div",{align:"center",children:(0,i.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,r)=>{r.d(n,{R:()=>l,x:()=>o});var s=r(6540);const i={},t=s.createContext(i);function l(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/e66382f6.aaa6c9c6.js b/docs/assets/js/e66382f6.ad26fd04.js similarity index 69% rename from docs/assets/js/e66382f6.aaa6c9c6.js rename to docs/assets/js/e66382f6.ad26fd04.js index b5cedec5..23fcfec6 100644 --- a/docs/assets/js/e66382f6.aaa6c9c6.js +++ b/docs/assets/js/e66382f6.ad26fd04.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1405],{287:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/v1.0.0-onfs-arch-7b3e91a84b2a24a378d13db769995c08.png"},8453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>o});var r=s(6540);const t={},i=r.createContext(t);function l(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),r.createElement(i.Provider,{value:n},e.children)}},9563:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"online-feature-store/v1.0.0/architecture","title":"Architecture","description":"The Online Feature Store (OnFS) is part of BharatMLStack, designed to support real-time ML workloads through low-latency feature retrieval and flexible feature ingestion pipelines. It ensures that features generated offline or online are immediately accessible for inference.","source":"@site/docs/online-feature-store/v1.0.0/architecture.md","sourceDirName":"online-feature-store/v1.0.0","slug":"/online-feature-store/v1.0.0/architecture","permalink":"/BharatMLStack/online-feature-store/v1.0.0/architecture","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/online-feature-store/v1.0.0/architecture.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"Architecture","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"v1.0.0","permalink":"/BharatMLStack/online-feature-store/v1.0.0"},"next":{"title":"Data Formats","permalink":"/BharatMLStack/online-feature-store/v1.0.0/data-formats"}}');var t=s(4848),i=s(8453);const l={title:"Architecture",sidebar_position:1},o="BharatMLStack - Online Feature Store (OnFS)",a={},c=[{value:"\ud83e\udde9 Key Components",id:"-key-components",level:2},{value:"1. <strong>Data Ingestion Paths</strong>",id:"1-data-ingestion-paths",level:3},{value:"a. <strong>Direct Push from Feature Engineering Jobs</strong>",id:"a-direct-push-from-feature-engineering-jobs",level:4},{value:"b. <strong>Push from Offline Feature Store</strong>",id:"b-push-from-offline-feature-store",level:4},{value:"c. <strong>Streaming Push via Apache Flink</strong>",id:"c-streaming-push-via-apache-flink",level:4},{value:"2. <strong>Message Queue: Kafka</strong>",id:"2-message-queue-kafka",level:3},{value:"3. <strong>Core Components</strong>",id:"3-core-components",level:3},{value:"\ud83e\udde0 <strong>Horizon Control Plane</strong>",id:"-horizon-control-plane",level:4},{value:"\ud83d\udd0d <strong>Trufflebox UI</strong>",id:"-trufflebox-ui",level:4},{value:"\u2699\ufe0f <strong>OnFS-Consumers</strong>",id:"\ufe0f-onfs-consumers",level:4},{value:"\ud83d\ude80 <strong>OnFS API Server</strong>",id:"-onfs-api-server",level:4},{value:"4. <strong>Online Databases</strong>",id:"4-online-databases",level:3},{value:"5. <strong>Clients for Serving</strong>",id:"5-clients-for-serving",level:3},{value:"6. <strong>Observability</strong>",id:"6-observability",level:3},{value:"\ud83d\udcbb Supported Environments",id:"-supported-environments",level:2},{value:"\ud83d\udc65 Target Users",id:"-target-users",level:2},{value:"\u2705 Benefits",id:"-benefits",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",hr:"hr",img:"img",li:"li",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"bharatmlstack---online-feature-store-onfs",children:"BharatMLStack - Online Feature Store (OnFS)"})}),"\n",(0,t.jsxs)(n.p,{children:["The Online Feature Store (OnFS) is part of ",(0,t.jsx)(n.strong,{children:"BharatMLStack"}),", designed to support real-time ML workloads through low-latency feature retrieval and flexible feature ingestion pipelines. It ensures that features generated offline or online are immediately accessible for inference."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"BharatMLStack's Online-feature-store Architecture",src:s(287).A+"",width:"2174",height:"1208"})}),"\n",(0,t.jsx)(n.h2,{id:"-key-components",children:"\ud83e\udde9 Key Components"}),"\n",(0,t.jsxs)(n.h3,{id:"1-data-ingestion-paths",children:["1. ",(0,t.jsx)(n.strong,{children:"Data Ingestion Paths"})]}),"\n",(0,t.jsxs)(n.h4,{id:"a-direct-push-from-feature-engineering-jobs",children:["a. ",(0,t.jsx)(n.strong,{children:"Direct Push from Feature Engineering Jobs"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Source:"})," Apache Spark"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Client:"})," ",(0,t.jsx)(n.code,{children:"spark_feature_push_client"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Flow:"})," Features are pushed directly to Kafka."]}),"\n"]}),"\n",(0,t.jsxs)(n.h4,{id:"b-push-from-offline-feature-store",children:["b. ",(0,t.jsx)(n.strong,{children:"Push from Offline Feature Store"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Source:"})," Delta Lake, GCS, or S3"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Flow:"})," Scheduled notebooks (",(0,t.jsx)(n.code,{children:"push_features_to_online-feature-stores.ipynb"}),") push to Kafka using the same ",(0,t.jsx)(n.code,{children:"spark_feature_push_client"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.h4,{id:"c-streaming-push-via-apache-flink",children:["c. ",(0,t.jsx)(n.strong,{children:"Streaming Push via Apache Flink"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Source:"})," Flink streaming jobs"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Client:"})," ",(0,t.jsx)(n.code,{children:"custom-producer"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Flow:"})," Real-time features sent to Kafka."]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.h3,{id:"2-message-queue-kafka",children:["2. ",(0,t.jsx)(n.strong,{children:"Message Queue: Kafka"})]}),"\n",(0,t.jsx)(n.p,{children:"Kafka serves as a decoupled buffer between producers (push clients) and consumers (OnFS ingestion workers), ensuring durability and backpressure handling."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.h3,{id:"3-core-components",children:["3. ",(0,t.jsx)(n.strong,{children:"Core Components"})]}),"\n",(0,t.jsxs)(n.h4,{id:"-horizon-control-plane",children:["\ud83e\udde0 ",(0,t.jsx)(n.strong,{children:"Horizon Control Plane"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Manages config distribution and metadata orchestration."}),"\n",(0,t.jsxs)(n.li,{children:["Stores schemas, feature group mappings, job configurations in ",(0,t.jsx)(n.code,{children:"etcd"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.h4,{id:"-trufflebox-ui",children:["\ud83d\udd0d ",(0,t.jsx)(n.strong,{children:"Trufflebox UI"})]}),"\n",(0,t.jsx)(n.p,{children:"Frontend interface for managing the ML Feature Store ecosystem:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Feature Catalog"})," \u2013 Browse, search, and inspect registered features and groups."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Store and Job Registry"})," \u2013 View and manage ingestion jobs, feature store states, and lineage."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Admin Ops"})," \u2013 Approve or reject feature group pushes and schema edits."]}),"\n",(0,t.jsxs)(n.li,{children:["Designed for use by ",(0,t.jsx)(n.strong,{children:"Data Scientists, MLEs"}),", and ",(0,t.jsx)(n.strong,{children:"Platform Admins"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.h4,{id:"\ufe0f-onfs-consumers",children:["\u2699\ufe0f ",(0,t.jsx)(n.strong,{children:"OnFS-Consumers"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Kafka consumers that read and validate feature messages."}),"\n",(0,t.jsx)(n.li,{children:"Responsible for persisting features to online databases (Redis, ScyllaDB, DragonflyDB)."}),"\n"]}),"\n",(0,t.jsxs)(n.h4,{id:"-onfs-api-server",children:["\ud83d\ude80 ",(0,t.jsx)(n.strong,{children:"OnFS API Server"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["gRPC server exposing interfaces for:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Real-time feature persistence."}),"\n",(0,t.jsx)(n.li,{children:"Low-latency feature retrieval."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Access controlled and schema-validated via ",(0,t.jsx)(n.code,{children:"etcd"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.h3,{id:"4-online-databases",children:["4. ",(0,t.jsx)(n.strong,{children:"Online Databases"})]}),"\n",(0,t.jsx)(n.p,{children:"Stores real-time features for high-performance retrieval:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.strong,{children:"DragonflyDB"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.strong,{children:"Redis"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.strong,{children:"ScyllaDB"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.h3,{id:"5-clients-for-serving",children:["5. ",(0,t.jsx)(n.strong,{children:"Clients for Serving"})]}),"\n",(0,t.jsx)(n.p,{children:"Applications use client SDKs to fetch features:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Go SDK"}),": ",(0,t.jsx)(n.code,{children:"go-sdk"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Python SDK"}),": ",(0,t.jsx)(n.code,{children:"grpc-feature-client"})]}),"\n",(0,t.jsx)(n.li,{children:"Used in backend inference apps to request features using entity keys."}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.h3,{id:"6-observability",children:["6. ",(0,t.jsx)(n.strong,{children:"Observability"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Prometheus"})," \u2013 Metrics collection (e.g., ingest lag, QPS, latency)."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Grafana"})," \u2013 Dashboard for platform health, feature access, ingestion success/failure."]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"-supported-environments",children:"\ud83d\udcbb Supported Environments"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Kubernetes (K8s)"}),"\n",(0,t.jsx)(n.li,{children:"Google Kubernetes Engine (GKE)"}),"\n",(0,t.jsx)(n.li,{children:"Amazon EKS"}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"-target-users",children:"\ud83d\udc65 Target Users"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"User"}),(0,t.jsx)(n.th,{children:"Role"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Data Scientists"}),(0,t.jsx)(n.td,{children:"Browse features, define jobs, approve/reject changes via Trufflebox UI"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"MLEs"}),(0,t.jsx)(n.td,{children:"Develop and push features using Spark/Flink/notebooks"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Infra Admins"}),(0,t.jsx)(n.td,{children:"Manage store lifecycle, metadata, and approvals"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Backend Devs"}),(0,t.jsx)(n.td,{children:"Use SDKs to retrieve features in Go/Python inference services"})]})]})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"-benefits",children:"\u2705 Benefits"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Unified real-time and offline ingestion."}),"\n",(0,t.jsx)(n.li,{children:"Low-latency inference-ready features."}),"\n",(0,t.jsx)(n.li,{children:"Config-driven orchestration."}),"\n",(0,t.jsx)(n.li,{children:"Built-in approval workflows via Trufflebox."}),"\n",(0,t.jsx)(n.li,{children:"Scalable across thousands of entities and feature groups."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,t.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,t.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,t.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\ud83d\udcac ",(0,t.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,t.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,t.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,t.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,t.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,t.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,t.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,t.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,t.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,t.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)("div",{align:"center",children:(0,t.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,t.jsx)("div",{align:"center",children:(0,t.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1405],{8453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>o});var r=s(6540);const t={},i=r.createContext(t);function l(e){const n=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),r.createElement(i.Provider,{value:n},e.children)}},9326:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/v1.0.0-onfs-arch-7b3e91a84b2a24a378d13db769995c08.png"},9563:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"online-feature-store/v1.0.0/architecture","title":"Architecture","description":"The Online Feature Store (OnFS) is part of BharatMLStack, designed to support real-time ML workloads through low-latency feature retrieval and flexible feature ingestion pipelines. It ensures that features generated offline or online are immediately accessible for inference.","source":"@site/docs/online-feature-store/v1.0.0/architecture.md","sourceDirName":"online-feature-store/v1.0.0","slug":"/online-feature-store/v1.0.0/architecture","permalink":"/BharatMLStack/online-feature-store/v1.0.0/architecture","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/online-feature-store/v1.0.0/architecture.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"Architecture","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"v1.0.0","permalink":"/BharatMLStack/online-feature-store/v1.0.0"},"next":{"title":"Data Formats","permalink":"/BharatMLStack/online-feature-store/v1.0.0/data-formats"}}');var t=s(4848),i=s(8453);const l={title:"Architecture",sidebar_position:1},o="BharatMLStack - Online Feature Store (OnFS)",a={},c=[{value:"\ud83e\udde9 Key Components",id:"-key-components",level:2},{value:"1. <strong>Data Ingestion Paths</strong>",id:"1-data-ingestion-paths",level:3},{value:"a. <strong>Direct Push from Feature Engineering Jobs</strong>",id:"a-direct-push-from-feature-engineering-jobs",level:4},{value:"b. <strong>Push from Offline Feature Store</strong>",id:"b-push-from-offline-feature-store",level:4},{value:"c. <strong>Streaming Push via Apache Flink</strong>",id:"c-streaming-push-via-apache-flink",level:4},{value:"2. <strong>Message Queue: Kafka</strong>",id:"2-message-queue-kafka",level:3},{value:"3. <strong>Core Components</strong>",id:"3-core-components",level:3},{value:"\ud83e\udde0 <strong>Horizon Control Plane</strong>",id:"-horizon-control-plane",level:4},{value:"\ud83d\udd0d <strong>Trufflebox UI</strong>",id:"-trufflebox-ui",level:4},{value:"\u2699\ufe0f <strong>OnFS-Consumers</strong>",id:"\ufe0f-onfs-consumers",level:4},{value:"\ud83d\ude80 <strong>OnFS API Server</strong>",id:"-onfs-api-server",level:4},{value:"4. <strong>Online Databases</strong>",id:"4-online-databases",level:3},{value:"5. <strong>Clients for Serving</strong>",id:"5-clients-for-serving",level:3},{value:"6. <strong>Observability</strong>",id:"6-observability",level:3},{value:"\ud83d\udcbb Supported Environments",id:"-supported-environments",level:2},{value:"\ud83d\udc65 Target Users",id:"-target-users",level:2},{value:"\u2705 Benefits",id:"-benefits",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Community & Support",id:"community--support",level:2},{value:"License",id:"license",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",hr:"hr",img:"img",li:"li",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"bharatmlstack---online-feature-store-onfs",children:"BharatMLStack - Online Feature Store (OnFS)"})}),"\n",(0,t.jsxs)(n.p,{children:["The Online Feature Store (OnFS) is part of ",(0,t.jsx)(n.strong,{children:"BharatMLStack"}),", designed to support real-time ML workloads through low-latency feature retrieval and flexible feature ingestion pipelines. It ensures that features generated offline or online are immediately accessible for inference."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"BharatMLStack's Online-feature-store Architecture",src:s(9326).A+"",width:"2174",height:"1208"})}),"\n",(0,t.jsx)(n.h2,{id:"-key-components",children:"\ud83e\udde9 Key Components"}),"\n",(0,t.jsxs)(n.h3,{id:"1-data-ingestion-paths",children:["1. ",(0,t.jsx)(n.strong,{children:"Data Ingestion Paths"})]}),"\n",(0,t.jsxs)(n.h4,{id:"a-direct-push-from-feature-engineering-jobs",children:["a. ",(0,t.jsx)(n.strong,{children:"Direct Push from Feature Engineering Jobs"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Source:"})," Apache Spark"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Client:"})," ",(0,t.jsx)(n.code,{children:"spark_feature_push_client"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Flow:"})," Features are pushed directly to Kafka."]}),"\n"]}),"\n",(0,t.jsxs)(n.h4,{id:"b-push-from-offline-feature-store",children:["b. ",(0,t.jsx)(n.strong,{children:"Push from Offline Feature Store"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Source:"})," Delta Lake, GCS, or S3"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Flow:"})," Scheduled notebooks (",(0,t.jsx)(n.code,{children:"push_features_to_online-feature-stores.ipynb"}),") push to Kafka using the same ",(0,t.jsx)(n.code,{children:"spark_feature_push_client"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.h4,{id:"c-streaming-push-via-apache-flink",children:["c. ",(0,t.jsx)(n.strong,{children:"Streaming Push via Apache Flink"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Source:"})," Flink streaming jobs"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Client:"})," ",(0,t.jsx)(n.code,{children:"custom-producer"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Flow:"})," Real-time features sent to Kafka."]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.h3,{id:"2-message-queue-kafka",children:["2. ",(0,t.jsx)(n.strong,{children:"Message Queue: Kafka"})]}),"\n",(0,t.jsx)(n.p,{children:"Kafka serves as a decoupled buffer between producers (push clients) and consumers (OnFS ingestion workers), ensuring durability and backpressure handling."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.h3,{id:"3-core-components",children:["3. ",(0,t.jsx)(n.strong,{children:"Core Components"})]}),"\n",(0,t.jsxs)(n.h4,{id:"-horizon-control-plane",children:["\ud83e\udde0 ",(0,t.jsx)(n.strong,{children:"Horizon Control Plane"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Manages config distribution and metadata orchestration."}),"\n",(0,t.jsxs)(n.li,{children:["Stores schemas, feature group mappings, job configurations in ",(0,t.jsx)(n.code,{children:"etcd"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.h4,{id:"-trufflebox-ui",children:["\ud83d\udd0d ",(0,t.jsx)(n.strong,{children:"Trufflebox UI"})]}),"\n",(0,t.jsx)(n.p,{children:"Frontend interface for managing the ML Feature Store ecosystem:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Feature Catalog"})," \u2013 Browse, search, and inspect registered features and groups."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Store and Job Registry"})," \u2013 View and manage ingestion jobs, feature store states, and lineage."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Admin Ops"})," \u2013 Approve or reject feature group pushes and schema edits."]}),"\n",(0,t.jsxs)(n.li,{children:["Designed for use by ",(0,t.jsx)(n.strong,{children:"Data Scientists, MLEs"}),", and ",(0,t.jsx)(n.strong,{children:"Platform Admins"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.h4,{id:"\ufe0f-onfs-consumers",children:["\u2699\ufe0f ",(0,t.jsx)(n.strong,{children:"OnFS-Consumers"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Kafka consumers that read and validate feature messages."}),"\n",(0,t.jsx)(n.li,{children:"Responsible for persisting features to online databases (Redis, ScyllaDB, DragonflyDB)."}),"\n"]}),"\n",(0,t.jsxs)(n.h4,{id:"-onfs-api-server",children:["\ud83d\ude80 ",(0,t.jsx)(n.strong,{children:"OnFS API Server"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["gRPC server exposing interfaces for:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Real-time feature persistence."}),"\n",(0,t.jsx)(n.li,{children:"Low-latency feature retrieval."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Access controlled and schema-validated via ",(0,t.jsx)(n.code,{children:"etcd"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.h3,{id:"4-online-databases",children:["4. ",(0,t.jsx)(n.strong,{children:"Online Databases"})]}),"\n",(0,t.jsx)(n.p,{children:"Stores real-time features for high-performance retrieval:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.strong,{children:"DragonflyDB"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.strong,{children:"Redis"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.strong,{children:"ScyllaDB"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.h3,{id:"5-clients-for-serving",children:["5. ",(0,t.jsx)(n.strong,{children:"Clients for Serving"})]}),"\n",(0,t.jsx)(n.p,{children:"Applications use client SDKs to fetch features:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Go SDK"}),": ",(0,t.jsx)(n.code,{children:"go-sdk"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Python SDK"}),": ",(0,t.jsx)(n.code,{children:"grpc-feature-client"})]}),"\n",(0,t.jsx)(n.li,{children:"Used in backend inference apps to request features using entity keys."}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.h3,{id:"6-observability",children:["6. ",(0,t.jsx)(n.strong,{children:"Observability"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Prometheus"})," \u2013 Metrics collection (e.g., ingest lag, QPS, latency)."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Grafana"})," \u2013 Dashboard for platform health, feature access, ingestion success/failure."]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"-supported-environments",children:"\ud83d\udcbb Supported Environments"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Kubernetes (K8s)"}),"\n",(0,t.jsx)(n.li,{children:"Google Kubernetes Engine (GKE)"}),"\n",(0,t.jsx)(n.li,{children:"Amazon EKS"}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"-target-users",children:"\ud83d\udc65 Target Users"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"User"}),(0,t.jsx)(n.th,{children:"Role"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Data Scientists"}),(0,t.jsx)(n.td,{children:"Browse features, define jobs, approve/reject changes via Trufflebox UI"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"MLEs"}),(0,t.jsx)(n.td,{children:"Develop and push features using Spark/Flink/notebooks"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Infra Admins"}),(0,t.jsx)(n.td,{children:"Manage store lifecycle, metadata, and approvals"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Backend Devs"}),(0,t.jsx)(n.td,{children:"Use SDKs to retrieve features in Go/Python inference services"})]})]})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"-benefits",children:"\u2705 Benefits"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Unified real-time and offline ingestion."}),"\n",(0,t.jsx)(n.li,{children:"Low-latency inference-ready features."}),"\n",(0,t.jsx)(n.li,{children:"Config-driven orchestration."}),"\n",(0,t.jsx)(n.li,{children:"Built-in approval workflows via Trufflebox."}),"\n",(0,t.jsx)(n.li,{children:"Scalable across thousands of entities and feature groups."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,t.jsxs)(n.p,{children:["We welcome contributions from the community! Please see our ",(0,t.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})," for details on how to get started."]}),"\n",(0,t.jsx)(n.h2,{id:"community--support",children:"Community & Support"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\ud83d\udcac ",(0,t.jsx)(n.strong,{children:"Discord"}),": Join our ",(0,t.jsx)(n.a,{href:"https://discord.gg/XkT7XsV2AU",children:"community chat"})]}),"\n",(0,t.jsxs)(n.li,{children:["\ud83d\udc1b ",(0,t.jsx)(n.strong,{children:"Issues"}),": Report bugs and request features on ",(0,t.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/issues",children:"GitHub Issues"})]}),"\n",(0,t.jsxs)(n.li,{children:["\ud83d\udce7 ",(0,t.jsx)(n.strong,{children:"Email"}),": Contact us at ",(0,t.jsx)(n.a,{href:"mailto:ml-oss@meesho.com",children:"ml-oss@meesho.com"})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"license",children:"License"}),"\n",(0,t.jsxs)(n.p,{children:["BharatMLStack is open-source software licensed under the ",(0,t.jsx)(n.a,{href:"https://github.com/Meesho/BharatMLStack/blob/main/LICENSE.md",children:"BharatMLStack Business Source License 1.1"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)("div",{align:"center",children:(0,t.jsx)("strong",{children:"Built with \u2764\ufe0f for the ML community from Meesho"})}),"\n",(0,t.jsx)("div",{align:"center",children:(0,t.jsx)("strong",{children:"If you find this useful, \u2b50\ufe0f the repo \u2014 your support means the world to us!"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/docs/assets/js/e8202a51.49541ad2.js b/docs/assets/js/e8202a51.49541ad2.js new file mode 100644 index 00000000..03d054d6 --- /dev/null +++ b/docs/assets/js/e8202a51.49541ad2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2771],{1185:(t,e,i)=>{i.r(e),i.d(e,{assets:()=>d,contentTitle:()=>h,default:()=>g,frontMatter:()=>l,metadata:()=>s,toc:()=>x});const s=JSON.parse('{"id":"numerix/v1.0.0/benchmarks","title":"Benchmarks","description":"This PoC measures the performance of vector addition in Rust with and without compiler SIMD optimizations. Requests consist of repeated fixed-size vector addition operations processed in parallel by the CPU. These results provide perspective on how much faster SIMD makes vectorized computations, and similar improvements are expected for other vectorized operations in Numerix.","source":"@site/docs/numerix/v1.0.0/benchmarks.md","sourceDirName":"numerix/v1.0.0","slug":"/numerix/v1.0.0/benchmarks","permalink":"/BharatMLStack/numerix/v1.0.0/benchmarks","draft":false,"unlisted":false,"editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/docs/numerix/v1.0.0/benchmarks.md","tags":[],"version":"current","sidebarPosition":2,"frontMatter":{"title":"Benchmarks","sidebar_position":2},"sidebar":"tutorialSidebar","previous":{"title":"Architecture","permalink":"/BharatMLStack/numerix/v1.0.0/architecture"},"next":{"title":"Key Functionalities","permalink":"/BharatMLStack/numerix/v1.0.0/functionalities"}}');var r=i(4848),n=i(8453);const l={title:"Benchmarks",sidebar_position:2},h="Benchmarks (PoC)",d={},x=[{value:"System Configuration",id:"system-configuration",level:2},{value:"Vector Addition Performance",id:"vector-addition-performance",level:2},{value:"With SIMD",id:"with-simd",level:3},{value:"Without SIMD",id:"without-simd",level:3},{value:"Observations",id:"observations",level:2}];function c(t){const e={blockquote:"blockquote",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,n.R)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"benchmarks-poc",children:"Benchmarks (PoC)"})}),"\n",(0,r.jsxs)(e.p,{children:["This PoC measures the performance of ",(0,r.jsx)(e.strong,{children:"vector addition"})," in Rust ",(0,r.jsx)(e.strong,{children:"with and without compiler SIMD optimizations"}),". Requests consist of repeated fixed-size vector addition operations processed in parallel by the CPU. These results provide perspective on ",(0,r.jsx)(e.strong,{children:"how much faster SIMD makes vectorized computations"}),", and similar improvements are expected for other vectorized operations in Numerix."]}),"\n",(0,r.jsx)(e.h2,{id:"system-configuration",children:"System Configuration"}),"\n",(0,r.jsxs)(e.ul,{children:["\n",(0,r.jsxs)(e.li,{children:[(0,r.jsx)(e.strong,{children:"Instance Type"}),": c4a-highcpu-16"]}),"\n",(0,r.jsxs)(e.li,{children:[(0,r.jsx)(e.strong,{children:"Processor"}),": Google Axion (ARMv9, 64-bit)"]}),"\n",(0,r.jsxs)(e.li,{children:[(0,r.jsx)(e.strong,{children:"SIMD Extension"}),": SVE2"]}),"\n",(0,r.jsxs)(e.li,{children:[(0,r.jsx)(e.strong,{children:"OS"}),": Linux (Ubuntu 22.04)"]}),"\n",(0,r.jsxs)(e.li,{children:[(0,r.jsx)(e.strong,{children:"Rust Version"}),": rustc 1.80.0"]}),"\n",(0,r.jsxs)(e.li,{children:[(0,r.jsx)(e.strong,{children:"Target Triple"}),": aarch64-unknown-linux-gnu"]}),"\n"]}),"\n",(0,r.jsx)(e.h2,{id:"vector-addition-performance",children:"Vector Addition Performance"}),"\n",(0,r.jsx)(e.h3,{id:"with-simd",children:"With SIMD"}),"\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{style:{textAlign:"right"},children:"Vector Dim"}),(0,r.jsx)(e.th,{style:{textAlign:"right"},children:"ns per op"}),(0,r.jsx)(e.th,{style:{textAlign:"right"},children:"Iterations"}),(0,r.jsx)(e.th,{style:{textAlign:"right"},children:"Throughput (GiB/s)"}),(0,r.jsx)(e.th,{style:{textAlign:"right"},children:"Total CPU (raw)"}),(0,r.jsx)(e.th,{style:{textAlign:"right"},children:"Total CPU (normalized)"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"10"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"0.39626 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"170,057,457,941"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"376.04"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1564%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"97.75%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"50"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"0.6641 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"94,342,709,095"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1121.9"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1590%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"99.38%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"100"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1.1522 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"51,705,835,397"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1286.9"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1560%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"97.50%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"500"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"5.0649 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"12,061,753,661"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1471"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1538%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"96.12%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"9.648 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"6,488,848,705"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1544.5"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1570%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"98.12%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"5000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"52.925 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1,169,316,813"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1407.8"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1590%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"99.38%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"10000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"114.68 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"555,779,981"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1299.4"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1592%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"99.50%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"50000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"644.60 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"94,372,153"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1155.9"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1560%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"97.50%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"100000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1.4530 \xb5s"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"42,502,201"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1025.5"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1526%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"95.38%"})]})]})]}),"\n",(0,r.jsx)(e.h3,{id:"without-simd",children:"Without SIMD"}),"\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{style:{textAlign:"right"},children:"Vector Dim"}),(0,r.jsx)(e.th,{style:{textAlign:"right"},children:"ns per op"}),(0,r.jsx)(e.th,{style:{textAlign:"right"},children:"Iterations"}),(0,r.jsx)(e.th,{style:{textAlign:"right"},children:"Throughput (GiB/s)"}),(0,r.jsx)(e.th,{style:{textAlign:"right"},children:"Total CPU (raw)"}),(0,r.jsx)(e.th,{style:{textAlign:"right"},children:"Total CPU (normalized)"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"10"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"3.196 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1,000,000,000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"25.03"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1313%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"82.06%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"50"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"3.866 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1,000,000,000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"103.46"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1417%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"88.56%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"100"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"5.867 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1,000,000,000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"136.35"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1495%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"93.44%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"500"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"19.25 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1,000,000,000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"207.81"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1600%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"100.00%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"33.91 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1,000,000,000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"235.92"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1600%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"100.00%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"5000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"162.1 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"448,785,386"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"246.71"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1600%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"100.00%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"10000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"332.0 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"208,428,151"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"240.94"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1600%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"100.00%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"50000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1,740 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"39,247,646"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"229.93"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1600%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"100.00%"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"100000"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"3,401 ns"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"19,598,293"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"235.24"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"1600%"}),(0,r.jsx)(e.td,{style:{textAlign:"right"},children:"100.00%"})]})]})]}),"\n",(0,r.jsxs)(e.blockquote,{children:["\n",(0,r.jsx)(e.p,{children:"Normalization: Total CPU (normalized) = Total CPU (raw) / 16, since 1600% equals full utilization on a 16\u2011core machine."}),"\n"]}),"\n",(0,r.jsx)(e.h2,{id:"observations",children:"Observations"}),"\n",(0,r.jsxs)(e.ul,{children:["\n",(0,r.jsxs)(e.li,{children:[(0,r.jsx)(e.strong,{children:"SIMD provides large speedups across all vector sizes"}),": overall throughput improvements range from roughly ",(0,r.jsx)(e.strong,{children:"4\u201315\xd7"})," versus Without SIMD."]}),"\n",(0,r.jsxs)(e.li,{children:["For small vectors (10\u2013100), throughput gains are about ",(0,r.jsx)(e.strong,{children:"9\u201315\xd7"}),", with ns/op reduced proportionally."]}),"\n",(0,r.jsxs)(e.li,{children:["For larger vectors (500\u2013100000), speedups stabilize around ",(0,r.jsx)(e.strong,{children:"~4\u20137\xd7"})," as memory bandwidth pressure increases."]}),"\n",(0,r.jsxs)(e.li,{children:[(0,r.jsx)(e.strong,{children:"CPU saturation"}),": Without SIMD reaches 100% normalized CPU at and beyond 500 elements, whereas With SIMD typically operates at ~95\u201399% normalized CPU yet delivers substantially higher throughput at similar CPU."]}),"\n",(0,r.jsxs)(e.li,{children:[(0,r.jsx)(e.strong,{children:"Per\u2011CPU efficiency"}),": With SIMD, throughput per unit of CPU is much higher, reflecting better vector unit utilization and fewer instructions per element."]}),"\n",(0,r.jsx)(e.li,{children:"Absolute values depend on hardware and load; the relative differential reflects the benefit of compiler SIMD optimizations."}),"\n"]}),"\n",(0,r.jsxs)(e.blockquote,{children:["\n",(0,r.jsx)(e.p,{children:"\u26a0 Note: Absolute numbers depend on CPU frequency, memory locality, and system load. These results are meant\nto show relative SIMD benefits."}),"\n"]})]})}function g(t={}){const{wrapper:e}={...(0,n.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(c,{...t})}):c(t)}},8453:(t,e,i)=>{i.d(e,{R:()=>l,x:()=>h});var s=i(6540);const r={},n=s.createContext(r);function l(t){const e=s.useContext(n);return s.useMemo(function(){return"function"==typeof t?t(e):{...e,...t}},[e,t])}function h(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:l(t.components),s.createElement(n.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/f2c141e4.e3b70339.js b/docs/assets/js/f2c141e4.7dc49a6b.js similarity index 68% rename from docs/assets/js/f2c141e4.e3b70339.js rename to docs/assets/js/f2c141e4.7dc49a6b.js index 6ac4e93c..6d7c497b 100644 --- a/docs/assets/js/f2c141e4.e3b70339.js +++ b/docs/assets/js/f2c141e4.7dc49a6b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1909],{161:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>c,frontMatter:()=>a,metadata:()=>t,toc:()=>d});var t=i(3983),s=i(4848),r=i(8453);const a={slug:"post-one",title:"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)",authors:["adarsha","aditya","bhawani","jigar"],date:new Date("2022-11-15T00:00:00.000Z"),tags:["online-feature-store","interaction-store","mlplatform","meesho"]},o=void 0,l={authorsImageUrls:[void 0,void 0,void 0,void 0]},d=[{value:"The Genesis: How a Friday Night Roast Sparked Meesho\u2019s ML Platform",id:"the-genesis-how-a-friday-night-roast-sparked-meeshos-ml-platform",level:2},{value:"The Turning Point: From Batch to Real-Time",id:"the-turning-point-from-batch-to-real-time",level:2},{value:"First Generation Design",id:"first-generation-design",level:2},{value:"1. IOP Framework: A Real-Time DAG Executor",id:"1-iop-framework-a-real-time-dag-executor",level:3},{value:"2. Online Feature Store - 0th Version",id:"2-online-feature-store---0th-version",level:3},{value:"3. Interaction Store - 0th Version",id:"3-interaction-store---0th-version",level:3},{value:"Building the Online Feature Store - 0th Version",id:"building-the-online-feature-store---0th-version",level:2},{value:"Choosing the Right Tech Stack",id:"choosing-the-right-tech-stack",level:3},{value:"Streamlining the Data Flow",id:"streamlining-the-data-flow",level:3},{value:"The Challenges: Data Format and Storage",id:"the-challenges-data-format-and-storage",level:2},{value:"Feature Consistency",id:"feature-consistency",level:3},{value:"TTL Granularity",id:"ttl-granularity",level:3},{value:"Extensibility Across Databases",id:"extensibility-across-databases",level:3},{value:"Overcoming Technical Constraints",id:"overcoming-technical-constraints",level:2},{value:"The Solution: Schema Separation",id:"the-solution-schema-separation",level:2},{value:"Tracking Changes in Feature Groups",id:"tracking-changes-in-feature-groups",level:2},{value:"Common Real-World Scenarios:",id:"common-real-world-scenarios",level:3},{value:"The Solution: Schema Versioning",id:"the-solution-schema-versioning",level:2},{value:"Backward Compatibility",id:"backward-compatibility",level:3},{value:"Partial Availability Handling",id:"partial-availability-handling",level:3},{value:"Safe Writes Without Pipeline Pauses",id:"safe-writes-without-pipeline-pauses",level:3},{value:"Interaction Store - 0th Version",id:"interaction-store---0th-version",level:2},{value:"Event Ingestion",id:"event-ingestion",level:2},{value:"Storage Design",id:"storage-design",level:2},{value:"Why Redis?",id:"why-redis",level:3},{value:"Storage Structure",id:"storage-structure",level:3},{value:"Built-in Guardrails",id:"built-in-guardrails",level:3},{value:"Conclusion: Laying the Foundation for Real-Time ML",id:"conclusion-laying-the-foundation-for-real-time-ml",level:2}];function h(e){const n={a:"a",br:"br",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"BharatMLStack",src:i(9930).A+"",width:"1472",height:"892"})}),"\n",(0,s.jsx)(n.h2,{id:"the-genesis-how-a-friday-night-roast-sparked-meeshos-ml-platform",children:"The Genesis: How a Friday Night Roast Sparked Meesho\u2019s ML Platform"}),"\n",(0,s.jsx)(n.p,{children:"It all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting\u2014until one remark hit a little too close to home:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.em,{children:'"Why are we still crunching data for Monthly Active Users (MAU) when the next day it\u2019s all about Daily Active Users (DAU)?"'})}),"\n",(0,s.jsx)(n.p,{children:"The laughter died down, and the question lingered. When we regrouped on Monday\u2014clear-headed and slightly reflective\u2014we decided to dig into the numbers. What they discovered was quite revealing: a large portion of compute resources wasn\u2019t being put to good use.\nMuch of the system\u2019s effort was spent supporting users who weren\u2019t actively engaging, and even for new users, the experience wasn\u2019t optimized to make a meaningful impact."}),"\n",(0,s.jsxs)(n.p,{children:["At the same time, Meesho had just launched a company-wide initiative to reduce costs\u2014and every team had to contribute. This realization sparked the journey that would eventually lead to the ",(0,s.jsx)(n.strong,{children:"Meesho ML Platform"}),", known today as ",(0,s.jsx)(n.strong,{children:"BharatMLStack"}),"."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(3518).A+"",width:"1600",height:"1078"})}),"\n",(0,s.jsx)(n.p,{children:"Before the ML Platform, our recommendation and ranking pipelines followed a batch processing approach:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Data Ingestion"}),": The Data Platform team executed ETL jobs to ingest raw user data\u2014including user profiles, interaction logs, and product impressions\u2014into designated S3 buckets."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Layer 1"}),": Embedding Generation: On the Data Science side, Spark jobs pulled data from multiple S3 sources, cleaned and preprocessed it, and applied matrix factorization to generate user and item embeddings. The processed data and embeddings were then stored back in S3 in a structured format."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Layer 2"}),": Candidate Generation (CG): In this stage, Spark jobs leveraged embeddings and historical interaction data to generate candidate recommendations for users. These candidate lists were subsequently written to S3."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Layer 3"}),": Ranking and Merging \u2013 A final round of processing ranked the generated candidates using ML models, combined different candidate lists, and stored the final ranked recommendations in a caching system."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Serving"}),': A microservice retrieved ranked recommendations from an in-memory data store via exposed APIs, delivering personalized listings across key surfaces such as "For You" and Category Landing Pages (CLP).']}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This approach held up well\u2014until Meesho started seeing a significant surge in traffic."}),"\n",(0,s.jsx)(n.h2,{id:"the-turning-point-from-batch-to-real-time",children:"The Turning Point: From Batch to Real-Time"}),"\n",(0,s.jsxs)(n.p,{children:["At this time, the team was iterating on new ",(0,s.jsx)(n.strong,{children:"Ranker models"}),", and real-time inference seemed like the next logical step. But Rankers needed ",(0,s.jsx)(n.strong,{children:"real-time feature retrieval"}),", which meant an ",(0,s.jsx)(n.strong,{children:"online feature store"})," had to be built first."]}),"\n",(0,s.jsxs)(n.p,{children:["Exploring open-source options led to ",(0,s.jsx)(n.strong,{children:"cost vs. performance trade-offs"}),", but Meesho\u2019s surging traffic meant that ",(0,s.jsx)(n.strong,{children:"latency and stability were non-negotiable"}),". After multiple debates and stakeholder discussions, a bold decision was made:"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.em,{children:"We would build our own feature store."})}),"\n",(0,s.jsxs)(n.p,{children:["Meanwhile, efforts began to bring ",(0,s.jsx)(n.strong,{children:"Candidate Generators (CGs)"})," to real-time. The challenge? ",(0,s.jsx)(n.strong,{children:"Storing and retrieving user interactions quickly enough"})," to power real-time recommendations."]}),"\n",(0,s.jsxs)(n.p,{children:["As the team dove deeper, a new roadblock emerged:",(0,s.jsx)(n.br,{}),"\n","Our ML jobs were orchestrated using ",(0,s.jsx)(n.strong,{children:"Airflow DAGs"}),", giving data scientists flexibility in experimentation. But transitioning to real-time execution threatened this agility. Every change would now require backend engineering support, ",(0,s.jsx)(n.strong,{children:"slowing down iteration cycles"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["That\u2019s when the idea struck:",(0,s.jsx)(n.br,{}),"\n","We needed a ",(0,s.jsx)(n.strong,{children:"framework for real-time DAG execution"}),"\u2014one that preserved the same flexibility as Airflow but worked for ",(0,s.jsx)(n.strong,{children:"streaming data"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This moment shaped the ",(0,s.jsx)(n.strong,{children:"next phase of our journey"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"first-generation-design",children:"First Generation Design"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(7131).A+"",width:"1600",height:"1006"})}),"\n",(0,s.jsx)(n.h1,{id:"laying-the-groundwork-the-first-gen-ml-platform",children:"Laying the Groundwork: The First-Gen ML Platform"}),"\n",(0,s.jsx)(n.p,{children:"To solve these challenges, the team built three foundational components:"}),"\n",(0,s.jsx)(n.h3,{id:"1-iop-framework-a-real-time-dag-executor",children:"1. IOP Framework: A Real-Time DAG Executor"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Reusable Nodes"}),": Each DAG node (e.g., an invocation to a CG service, a ranker, or a filter) had to be implemented only once. After that, it could be reused across any workflow by referencing it in config."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Config-driven Dynamic Graphs"}),": Execution graphs were defined as adjacency lists stored in ",(0,s.jsx)(n.strong,{children:"ZooKeeper"}),", allowing teams to modify the sequence or structure of operations without touching application code."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Plug-and-play CGs"}),": The Candidate Generator interface was preserved, so a single CG node could call any CG service by passing ",(0,s.jsx)(n.code,{children:"cg_name"})," in the request. This drastically reduced the code surface area and improved maintainability."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Production-Grade DAGs"}),": DAGs were designed to execute in ",(0,s.jsx)(n.strong,{children:"low-latency real-time environments"}),", with support for ",(0,s.jsx)(n.strong,{children:"parallel execution, retries, and branching"}),"."]}),"\n"]}),"\n",(0,s.jsx)("u",{children:(0,s.jsx)(n.a,{href:"https://www.meesho.io/blog/rebuilding-meeshos-ranking-platform",children:"More about IOP DAG"})}),"\n",(0,s.jsx)(n.h3,{id:"2-online-feature-store---0th-version",children:"2. Online Feature Store - 0th Version"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Used ",(0,s.jsx)(n.strong,{children:"Cassandra"})," and ",(0,s.jsx)(n.strong,{children:"Redis"})," for low-latency feature serving."]}),"\n",(0,s.jsxs)(n.li,{children:["Maintained feature consistency using ",(0,s.jsx)(n.strong,{children:"Feature Groups"})," with TTL-based expiry."]}),"\n",(0,s.jsxs)(n.li,{children:["A hybrid schema was used: feature keys stored in ",(0,s.jsx)(n.strong,{children:"ZooKeeper"}),", data stored in ",(0,s.jsx)(n.strong,{children:"compact arrays"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"3-interaction-store---0th-version",children:"3. Interaction Store - 0th Version"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Captured real-time user interactions like clicks, orders, and add-to-cart events."}),"\n",(0,s.jsxs)(n.li,{children:["Stored event data in ",(0,s.jsx)(n.strong,{children:"Redis ZSETs (sorted sets)"})," to enable fast lookups for recommendation engines."]}),"\n",(0,s.jsxs)(n.li,{children:["Provided an API to fetch a user's ",(0,s.jsxs)(n.strong,{children:["last ",(0,s.jsx)(n.em,{children:"k"})," interactions"]})," or ",(0,s.jsx)(n.strong,{children:"interactions within a time window"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["With these components in place, ",(0,s.jsx)(n.strong,{children:"real-time ML at Meesho became a reality"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"This was just the beginning."}),"\n",(0,s.jsx)(n.h2,{id:"building-the-online-feature-store---0th-version",children:"Building the Online Feature Store - 0th Version"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt text",src:i(5728).A+"",width:"1574",height:"562"})}),"\n",(0,s.jsx)(n.h3,{id:"choosing-the-right-tech-stack",children:"Choosing the Right Tech Stack"}),"\n",(0,s.jsxs)(n.p,{children:["We spent considerable time evaluating various databases, caches, and communication protocols for our ",(0,s.jsx)(n.strong,{children:"online feature store"}),". After carefully weighing ",(0,s.jsx)(n.strong,{children:"cost, latency, throughput"}),", and ",(0,s.jsx)(n.strong,{children:"operational stability"}),", we settled on a combination of:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Cassandra"})," and ",(0,s.jsx)(n.strong,{children:"Redis"})," for storage"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"gRPC + Proto3"})," as our communication layer"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"streamlining-the-data-flow",children:"Streamlining the Data Flow"}),"\n",(0,s.jsx)(n.p,{children:"To keep things simple in the initial version:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature engineering jobs"})," wrote raw outputs to an ",(0,s.jsx)(n.strong,{children:"S3 bucket"})]}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.strong,{children:"daily feature push job"}),":","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Read from S3"}),"\n",(0,s.jsxs)(n.li,{children:["Grouped related features into ",(0,s.jsx)(n.strong,{children:"Feature Groups"})," (ensuring consistency)"]}),"\n",(0,s.jsxs)(n.li,{children:["Pushed them to ",(0,s.jsx)(n.strong,{children:"Kafka"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"For features requiring frequent updates:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Ad-hoc jobs"})," computed features in higher frequency"]}),"\n",(0,s.jsxs)(n.li,{children:["These jobs pushed to both ",(0,s.jsx)(n.strong,{children:"Kafka"})," and ",(0,s.jsx)(n.strong,{children:"S3"})," (S3 preserved historical data for future model training)"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"the-challenges-data-format-and-storage",children:"The Challenges: Data Format and Storage"}),"\n",(0,s.jsxs)(n.p,{children:["One of the most critical design challenges was how to store feature data ",(0,s.jsx)(n.strong,{children:"efficiently and consistently"}),", especially in databases like ",(0,s.jsx)(n.strong,{children:"Cassandra"})," and ",(0,s.jsx)(n.strong,{children:"Redis"}),", which come with unique storage constraints."]}),"\n",(0,s.jsx)(n.p,{children:"We had to solve for three key requirements:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"feature-consistency",children:"Feature Consistency"}),"\n",(0,s.jsxs)(n.p,{children:["When a feature group contains features like ",(0,s.jsx)(n.code,{children:"order_count_1h"})," and ",(0,s.jsx)(n.code,{children:"click_count_1h"}),", both must reflect the ",(0,s.jsx)(n.strong,{children:"same time window"}),". Inconsistent updates would lead to ",(0,s.jsx)(n.strong,{children:"unreliable model predictions"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"ttl-granularity",children:"TTL Granularity"}),"\n",(0,s.jsxs)(n.p,{children:["Each feature group required an ",(0,s.jsx)(n.strong,{children:"expiry timestamp"}),", so that ",(0,s.jsx)(n.strong,{children:"all features within it expired together"}),"\u2014preserving consistency during reads."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"extensibility-across-databases",children:"Extensibility Across Databases"}),"\n",(0,s.jsxs)(n.p,{children:["We anticipated that infra needs would evolve. To future-proof our system, the data format was designed to be ",(0,s.jsx)(n.strong,{children:"decoupled from DB-specific layouts"}),", enabling portability to systems like ",(0,s.jsx)(n.strong,{children:"ScyllaDB"}),", ",(0,s.jsx)(n.strong,{children:"DynamoDB"}),", ",(0,s.jsx)(n.strong,{children:"HBase"}),", or ",(0,s.jsx)(n.strong,{children:"BigTable"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"overcoming-technical-constraints",children:"Overcoming Technical Constraints"}),"\n",(0,s.jsx)(n.p,{children:'At the time, we were using Cassandra, which not only imposed a soft limit of 75 columns per row, but also exhibited significant performance degradation as the number of columns increased further, particularly in memory constrained machines. Wide rows caused high memory usage during reads, unpredictable latencies due to heavy deserialization overhead, and inefficiencies during compactions and repairs. This ruled out the naive "one column per feature" approach. We needed a format that was compact, minimized the number of columns, and remained efficient and portable across different storage systems.'}),"\n",(0,s.jsx)(n.h2,{id:"the-solution-schema-separation",children:"The Solution: Schema Separation"}),"\n",(0,s.jsx)(n.p,{children:"We introduced the concept of Feature Groups\u2014logical groupings of features that must remain consistent with one another.\nTo represent these groups efficiently, we adopted a layered storage approach:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature Labels (Keys)"})," were stored in ZooKeeper, serving as the schema."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature Values"})," were stored as a comma-separated string array in Cassandra or Redis."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Expiry Timestamp and Schema Version"})," were appended using a semi-colon delimiter at the end of the string."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"feature_1_value,feature_2_value,feature_3_value;expiry_ts\n"})}),"\n",(0,s.jsx)(n.p,{children:"This format allowed:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Consistent writes and reads at the group level"}),"\n",(0,s.jsx)(n.li,{children:"Easy parsing of feature values using the schema lookup from ZooKeeper"}),"\n",(0,s.jsx)(n.li,{children:"Efficient storage with minimal DB column usage"}),"\n",(0,s.jsx)(n.li,{children:"Support for per-group TTLs and schema evolution"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"tracking-changes-in-feature-groups",children:"Tracking Changes in Feature Groups"}),"\n",(0,s.jsx)(n.p,{children:"Feature groups don\u2019t stay static. As models evolve, features get added, renamed, or removed. But schema changes often go live before the data is ready\u2014and stopping ingestion just to wait for everything to align isn't feasible."}),"\n",(0,s.jsx)(n.h3,{id:"common-real-world-scenarios",children:"Common Real-World Scenarios:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"A new feature is added to the schema, but ingestion jobs still use the older schema version."}),"\n",(0,s.jsx)(n.li,{children:"Ongoing writes don\u2019t include the newly added feature, and stopping ingestion would break freshness for existing features."}),"\n",(0,s.jsx)(n.li,{children:"During serving, models request a mix of old and new features, depending on rollout stages."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"the-solution-schema-versioning",children:"The Solution: Schema Versioning"}),"\n",(0,s.jsx)(n.p,{children:"We solved this with versioned feature group schemas, which unlocked several capabilities:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"backward-compatibility",children:"Backward Compatibility"}),"\n","Older ingestion jobs can continue writing using older schema versions. During reads, the system uses the schema version embedded in the value to interpret the data correctly."]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"partial-availability-handling",children:"Partial Availability Handling"}),"\n","During inference, if some features in the request aren\u2019t available (due to rollout delays or missing data), the system serves default values, ensuring the inference call doesn\u2019t fail."]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"safe-writes-without-pipeline-pauses",children:"Safe Writes Without Pipeline Pauses"}),"\n","With schema versioning, we no longer had to stop ingestion pipelines for schema updates. Writes using previous versions can continue safely, and downstream consumers evolve independently.\nThis design gave us the flexibility to move fast without breaking things\u2014preserving data quality, enabling experimentation, and ensuring reliability at scale."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(3190).A+"",width:"1600",height:"599"})}),"\n",(0,s.jsx)(n.h2,{id:"interaction-store---0th-version",children:"Interaction Store - 0th Version"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(1012).A+"",width:"1600",height:"518"})}),"\n",(0,s.jsxs)(n.p,{children:["To power real-time Candidate Generators (CGs), we needed fast access to user behavior signals\u2014like what a user recently clicked, ordered, or added to their cart. These interactions form the basis for many real-time recommendations, such as ",(0,s.jsx)(n.strong,{children:"Similar Products"}),", ",(0,s.jsx)(n.strong,{children:"People Also Viewed"}),", or ",(0,s.jsx)(n.strong,{children:"Recently Ordered Again"}),".\nFor the ",(0,s.jsx)(n.strong,{children:"0th version"})," of the Interaction Store, we focused on a design that was ",(0,s.jsx)(n.strong,{children:"simple, fast, and reliable"})," \u2014 optimized for high-throughput ingestion and low-latency lookups."]}),"\n",(0,s.jsx)(n.h2,{id:"event-ingestion",children:"Event Ingestion"}),"\n",(0,s.jsx)(n.p,{children:"We instrumented our backend services to emit key user interaction events to Kafka in real time. These included:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Click"}),"\n",(0,s.jsx)(n.li,{children:"Order"}),"\n",(0,s.jsx)(n.li,{children:"Add to Cart"}),"\n",(0,s.jsx)(n.li,{children:"Wishlist"}),"\n",(0,s.jsx)(n.li,{children:"Share"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Each event carried essential metadata:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"userId \u2014 uniquely identifies the user"}),"\n",(0,s.jsx)(n.li,{children:"productId \u2014 the item being interacted with"}),"\n",(0,s.jsx)(n.li,{children:"timestamp \u2014 the moment the interaction occurred"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This decoupled the interaction logging from storage, allowing ingestion and consumption to scale independently."}),"\n",(0,s.jsx)(n.h2,{id:"storage-design",children:"Storage Design"}),"\n",(0,s.jsx)(n.p,{children:"To store these events, we built Kafka consumers that processed the incoming streams and wrote the data into Redis, using sorted sets (ZSETs) as the primary data structure."}),"\n",(0,s.jsx)(n.h3,{id:"why-redis",children:"Why Redis?"}),"\n",(0,s.jsx)(n.p,{children:"Redis gave us:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Low-latency"})," reads and writes"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Time-ordered data"})," using ZSETs (via score = timestamp)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Native TTL support"}),", if needed in later versions"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"In-memory performance"})," \u2014ideal for real-time CGs"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"storage-structure",children:"Storage Structure"}),"\n",(0,s.jsx)(n.p,{children:"Each user\u2019s interactions were stored using a composite key format, uniquely identifying the user and interaction type. This structure allowed efficient organization and quick retrieval of recent activity for recommendation generation:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"userId_eventType \u2192 ZSET[...(pid, ts)...]\n"})}),"\n",(0,s.jsx)(n.p,{children:"Within each ZSET:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"timestamp"})," served as the score, maintaining temporal order"]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"productId"})," (optionally with metadata) was the ",(0,s.jsx)(n.strong,{children:"value"})]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This allowed us to efficiently retrieve the interactions with HTTP-based API server with two query modes:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Fetch the ",(0,s.jsx)(n.strong,{children:"last k interactions"})," of a specific type for a given user with ",(0,s.jsx)(n.code,{children:"ZREVRANGE(userId_eventType, count)"})]}),"\n",(0,s.jsxs)(n.li,{children:["Retrieve ",(0,s.jsx)(n.strong,{children:"all interactions within a time range"})," (e.g., last 24 hours) with ",(0,s.jsx)(n.code,{children:"ZREVRANGEBYSCORE(userId_eventType, timeRange)"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"built-in-guardrails",children:"Built-in Guardrails"}),"\n",(0,s.jsx)(n.p,{children:"Since Redis was the sole store, we implemented High Availability (HA) to prevent data loss. To optimize memory usage, we also enforced size limits per event type\u2014only storing the last k interactions per user, with older entries getting truncated."}),"\n",(0,s.jsx)(n.h2,{id:"conclusion-laying-the-foundation-for-real-time-ml",children:"Conclusion: Laying the Foundation for Real-Time ML"}),"\n",(0,s.jsxs)(n.p,{children:["In this first phase, we tackled the ",(0,s.jsx)(n.strong,{children:"fundamentals"}),"\u2014shifting from batch-based recommendations to a ",(0,s.jsx)(n.strong,{children:"real-time Recommendation"})," using ML platform that could keep up with Meesho\u2019s growth."]}),"\n",(0,s.jsxs)(n.p,{children:["With the ",(0,s.jsx)(n.strong,{children:"IOP Framework"}),", ",(0,s.jsx)(n.strong,{children:"Online Feature Store"}),", and ",(0,s.jsx)(n.strong,{children:"Interaction Store"}),", we built the core infrastructure to support real-time personalization at scale. These wins have already unlocked:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"\u2705 Faster, more dynamic recommendations for millions of users."}),"\n",(0,s.jsx)(n.li,{children:"\u2705 Better infrastructure efficiency, reducing wasted compute power."}),"\n",(0,s.jsx)(n.li,{children:"\u2705 A flexible, modular system that allows for further experimentation."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["But this is just the beginning. While we've solved key challenges, ",(0,s.jsx)(n.strong,{children:"certain roadblocks remain"})," \u2014from optimizing ",(0,s.jsx)(n.strong,{children:"cost-performance trade-offs"})," to ",(0,s.jsx)(n.strong,{children:"seamlessly evolving schemas"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This foundational work laid the path for a reliable and scalable ",(0,s.jsx)(n.strong,{children:"real-time feature serving layer"}),"."]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},1012:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/interaction-store-v0-68167b64c6e462ef2f177f0f86d55bda.png"},3190:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/schema-d699efc400ed0f83bba421c1f55ab211.png"},3518:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/old-batch-arch-bc2cedbc1fed0fc6f08479ba8fe52996.png"},3983:e=>{e.exports=JSON.parse('{"permalink":"/BharatMLStack/blog/post-one","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-one/index.md","source":"@site/blog/bharatmlstack-history/post-one/index.md","title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","description":"BharatMLStack","date":"2022-11-15T00:00:00.000Z","tags":[{"inline":true,"label":"online-feature-store","permalink":"/BharatMLStack/blog/tags/online-feature-store"},{"inline":true,"label":"interaction-store","permalink":"/BharatMLStack/blog/tags/interaction-store"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"}],"readingTime":10.25,"hasTruncateMarker":false,"authors":[{"name":"Adarsha Das","title":"Senior Architect @ Meesho","url":"https://github.com/a0d00kc","imageURL":"https://github.com/a0d00kc.png","key":"adarsha","page":null},{"name":"Aditya Kumar","title":"SDE-III @ Meesho","url":"https://github.com/Adit2607","imageURL":"https://github.com/Adit2607.png","key":"aditya","page":null},{"name":"Bhawani Singh","title":"SDE-IV @ Meesho","url":"https://github.com/singh-bhawani","imageURL":"https://github.com/singh-bhawani.png","key":"bhawani","page":null},{"name":"Jigar Dave","title":"SDE-IV @ Meesho","url":"https://github.com/jigarpatel26","imageURL":"https://github.com/jigarpatel26.png","key":"jigar","page":null}],"frontMatter":{"slug":"post-one","title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","authors":["adarsha","aditya","bhawani","jigar"],"date":"2022-11-15T00:00:00.000Z","tags":["online-feature-store","interaction-store","mlplatform","meesho"]},"unlisted":false}')},5728:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/online-feature-store-v0-86ec0010947ae24621f39ebd0d1729ca.png"},7131:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/first-gen-arch-7c0b286810aecb7eff42b48f51caee1f.png"},8453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>o});var t=i(6540);const s={},r=t.createContext(s);function a(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(r.Provider,{value:n},e.children)}},9930:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/bharatmlstack-72e1796337bfa224dee2a0f59ec4e2da.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1909],{161:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>c,frontMatter:()=>a,metadata:()=>t,toc:()=>d});var t=i(3983),s=i(4848),r=i(8453);const a={slug:"post-one",title:"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)",authors:["adarsha","aditya","bhawani","jigar"],date:new Date("2022-11-15T00:00:00.000Z"),tags:["online-feature-store","interaction-store","mlplatform","meesho"]},o=void 0,l={authorsImageUrls:[void 0,void 0,void 0,void 0]},d=[{value:"The Genesis: How a Friday Night Roast Sparked Meesho\u2019s ML Platform",id:"the-genesis-how-a-friday-night-roast-sparked-meeshos-ml-platform",level:2},{value:"The Turning Point: From Batch to Real-Time",id:"the-turning-point-from-batch-to-real-time",level:2},{value:"First Generation Design",id:"first-generation-design",level:2},{value:"1. IOP Framework: A Real-Time DAG Executor",id:"1-iop-framework-a-real-time-dag-executor",level:3},{value:"2. Online Feature Store - 0th Version",id:"2-online-feature-store---0th-version",level:3},{value:"3. Interaction Store - 0th Version",id:"3-interaction-store---0th-version",level:3},{value:"Building the Online Feature Store - 0th Version",id:"building-the-online-feature-store---0th-version",level:2},{value:"Choosing the Right Tech Stack",id:"choosing-the-right-tech-stack",level:3},{value:"Streamlining the Data Flow",id:"streamlining-the-data-flow",level:3},{value:"The Challenges: Data Format and Storage",id:"the-challenges-data-format-and-storage",level:2},{value:"Feature Consistency",id:"feature-consistency",level:3},{value:"TTL Granularity",id:"ttl-granularity",level:3},{value:"Extensibility Across Databases",id:"extensibility-across-databases",level:3},{value:"Overcoming Technical Constraints",id:"overcoming-technical-constraints",level:2},{value:"The Solution: Schema Separation",id:"the-solution-schema-separation",level:2},{value:"Tracking Changes in Feature Groups",id:"tracking-changes-in-feature-groups",level:2},{value:"Common Real-World Scenarios:",id:"common-real-world-scenarios",level:3},{value:"The Solution: Schema Versioning",id:"the-solution-schema-versioning",level:2},{value:"Backward Compatibility",id:"backward-compatibility",level:3},{value:"Partial Availability Handling",id:"partial-availability-handling",level:3},{value:"Safe Writes Without Pipeline Pauses",id:"safe-writes-without-pipeline-pauses",level:3},{value:"Interaction Store - 0th Version",id:"interaction-store---0th-version",level:2},{value:"Event Ingestion",id:"event-ingestion",level:2},{value:"Storage Design",id:"storage-design",level:2},{value:"Why Redis?",id:"why-redis",level:3},{value:"Storage Structure",id:"storage-structure",level:3},{value:"Built-in Guardrails",id:"built-in-guardrails",level:3},{value:"Conclusion: Laying the Foundation for Real-Time ML",id:"conclusion-laying-the-foundation-for-real-time-ml",level:2}];function h(e){const n={a:"a",br:"br",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"BharatMLStack",src:i(1164).A+"",width:"1396",height:"460"})}),"\n",(0,s.jsx)(n.h2,{id:"the-genesis-how-a-friday-night-roast-sparked-meeshos-ml-platform",children:"The Genesis: How a Friday Night Roast Sparked Meesho\u2019s ML Platform"}),"\n",(0,s.jsx)(n.p,{children:"It all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting\u2014until one remark hit a little too close to home:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.em,{children:'"Why are we still crunching data for Monthly Active Users (MAU) when the next day it\u2019s all about Daily Active Users (DAU)?"'})}),"\n",(0,s.jsx)(n.p,{children:"The laughter died down, and the question lingered. When we regrouped on Monday\u2014clear-headed and slightly reflective\u2014we decided to dig into the numbers. What they discovered was quite revealing: a large portion of compute resources wasn\u2019t being put to good use.\nMuch of the system\u2019s effort was spent supporting users who weren\u2019t actively engaging, and even for new users, the experience wasn\u2019t optimized to make a meaningful impact."}),"\n",(0,s.jsxs)(n.p,{children:["At the same time, Meesho had just launched a company-wide initiative to reduce costs\u2014and every team had to contribute. This realization sparked the journey that would eventually lead to the ",(0,s.jsx)(n.strong,{children:"Meesho ML Platform"}),", known today as ",(0,s.jsx)(n.strong,{children:"BharatMLStack"}),"."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(1757).A+"",width:"1600",height:"1078"})}),"\n",(0,s.jsx)(n.p,{children:"Before the ML Platform, our recommendation and ranking pipelines followed a batch processing approach:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Data Ingestion"}),": The Data Platform team executed ETL jobs to ingest raw user data\u2014including user profiles, interaction logs, and product impressions\u2014into designated S3 buckets."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Layer 1"}),": Embedding Generation: On the Data Science side, Spark jobs pulled data from multiple S3 sources, cleaned and preprocessed it, and applied matrix factorization to generate user and item embeddings. The processed data and embeddings were then stored back in S3 in a structured format."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Layer 2"}),": Candidate Generation (CG): In this stage, Spark jobs leveraged embeddings and historical interaction data to generate candidate recommendations for users. These candidate lists were subsequently written to S3."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Layer 3"}),": Ranking and Merging \u2013 A final round of processing ranked the generated candidates using ML models, combined different candidate lists, and stored the final ranked recommendations in a caching system."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Serving"}),': A microservice retrieved ranked recommendations from an in-memory data store via exposed APIs, delivering personalized listings across key surfaces such as "For You" and Category Landing Pages (CLP).']}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This approach held up well\u2014until Meesho started seeing a significant surge in traffic."}),"\n",(0,s.jsx)(n.h2,{id:"the-turning-point-from-batch-to-real-time",children:"The Turning Point: From Batch to Real-Time"}),"\n",(0,s.jsxs)(n.p,{children:["At this time, the team was iterating on new ",(0,s.jsx)(n.strong,{children:"Ranker models"}),", and real-time inference seemed like the next logical step. But Rankers needed ",(0,s.jsx)(n.strong,{children:"real-time feature retrieval"}),", which meant an ",(0,s.jsx)(n.strong,{children:"online feature store"})," had to be built first."]}),"\n",(0,s.jsxs)(n.p,{children:["Exploring open-source options led to ",(0,s.jsx)(n.strong,{children:"cost vs. performance trade-offs"}),", but Meesho\u2019s surging traffic meant that ",(0,s.jsx)(n.strong,{children:"latency and stability were non-negotiable"}),". After multiple debates and stakeholder discussions, a bold decision was made:"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.em,{children:"We would build our own feature store."})}),"\n",(0,s.jsxs)(n.p,{children:["Meanwhile, efforts began to bring ",(0,s.jsx)(n.strong,{children:"Candidate Generators (CGs)"})," to real-time. The challenge? ",(0,s.jsx)(n.strong,{children:"Storing and retrieving user interactions quickly enough"})," to power real-time recommendations."]}),"\n",(0,s.jsxs)(n.p,{children:["As the team dove deeper, a new roadblock emerged:",(0,s.jsx)(n.br,{}),"\n","Our ML jobs were orchestrated using ",(0,s.jsx)(n.strong,{children:"Airflow DAGs"}),", giving data scientists flexibility in experimentation. But transitioning to real-time execution threatened this agility. Every change would now require backend engineering support, ",(0,s.jsx)(n.strong,{children:"slowing down iteration cycles"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["That\u2019s when the idea struck:",(0,s.jsx)(n.br,{}),"\n","We needed a ",(0,s.jsx)(n.strong,{children:"framework for real-time DAG execution"}),"\u2014one that preserved the same flexibility as Airflow but worked for ",(0,s.jsx)(n.strong,{children:"streaming data"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This moment shaped the ",(0,s.jsx)(n.strong,{children:"next phase of our journey"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"first-generation-design",children:"First Generation Design"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(7848).A+"",width:"1600",height:"1006"})}),"\n",(0,s.jsx)(n.h1,{id:"laying-the-groundwork-the-first-gen-ml-platform",children:"Laying the Groundwork: The First-Gen ML Platform"}),"\n",(0,s.jsx)(n.p,{children:"To solve these challenges, the team built three foundational components:"}),"\n",(0,s.jsx)(n.h3,{id:"1-iop-framework-a-real-time-dag-executor",children:"1. IOP Framework: A Real-Time DAG Executor"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Reusable Nodes"}),": Each DAG node (e.g., an invocation to a CG service, a ranker, or a filter) had to be implemented only once. After that, it could be reused across any workflow by referencing it in config."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Config-driven Dynamic Graphs"}),": Execution graphs were defined as adjacency lists stored in ",(0,s.jsx)(n.strong,{children:"ZooKeeper"}),", allowing teams to modify the sequence or structure of operations without touching application code."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Plug-and-play CGs"}),": The Candidate Generator interface was preserved, so a single CG node could call any CG service by passing ",(0,s.jsx)(n.code,{children:"cg_name"})," in the request. This drastically reduced the code surface area and improved maintainability."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Production-Grade DAGs"}),": DAGs were designed to execute in ",(0,s.jsx)(n.strong,{children:"low-latency real-time environments"}),", with support for ",(0,s.jsx)(n.strong,{children:"parallel execution, retries, and branching"}),"."]}),"\n"]}),"\n",(0,s.jsx)("u",{children:(0,s.jsx)(n.a,{href:"https://www.meesho.io/blog/rebuilding-meeshos-ranking-platform",children:"More about IOP DAG"})}),"\n",(0,s.jsx)(n.h3,{id:"2-online-feature-store---0th-version",children:"2. Online Feature Store - 0th Version"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Used ",(0,s.jsx)(n.strong,{children:"Cassandra"})," and ",(0,s.jsx)(n.strong,{children:"Redis"})," for low-latency feature serving."]}),"\n",(0,s.jsxs)(n.li,{children:["Maintained feature consistency using ",(0,s.jsx)(n.strong,{children:"Feature Groups"})," with TTL-based expiry."]}),"\n",(0,s.jsxs)(n.li,{children:["A hybrid schema was used: feature keys stored in ",(0,s.jsx)(n.strong,{children:"ZooKeeper"}),", data stored in ",(0,s.jsx)(n.strong,{children:"compact arrays"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"3-interaction-store---0th-version",children:"3. Interaction Store - 0th Version"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Captured real-time user interactions like clicks, orders, and add-to-cart events."}),"\n",(0,s.jsxs)(n.li,{children:["Stored event data in ",(0,s.jsx)(n.strong,{children:"Redis ZSETs (sorted sets)"})," to enable fast lookups for recommendation engines."]}),"\n",(0,s.jsxs)(n.li,{children:["Provided an API to fetch a user's ",(0,s.jsxs)(n.strong,{children:["last ",(0,s.jsx)(n.em,{children:"k"})," interactions"]})," or ",(0,s.jsx)(n.strong,{children:"interactions within a time window"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["With these components in place, ",(0,s.jsx)(n.strong,{children:"real-time ML at Meesho became a reality"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"This was just the beginning."}),"\n",(0,s.jsx)(n.h2,{id:"building-the-online-feature-store---0th-version",children:"Building the Online Feature Store - 0th Version"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt text",src:i(5017).A+"",width:"1574",height:"562"})}),"\n",(0,s.jsx)(n.h3,{id:"choosing-the-right-tech-stack",children:"Choosing the Right Tech Stack"}),"\n",(0,s.jsxs)(n.p,{children:["We spent considerable time evaluating various databases, caches, and communication protocols for our ",(0,s.jsx)(n.strong,{children:"online feature store"}),". After carefully weighing ",(0,s.jsx)(n.strong,{children:"cost, latency, throughput"}),", and ",(0,s.jsx)(n.strong,{children:"operational stability"}),", we settled on a combination of:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Cassandra"})," and ",(0,s.jsx)(n.strong,{children:"Redis"})," for storage"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"gRPC + Proto3"})," as our communication layer"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"streamlining-the-data-flow",children:"Streamlining the Data Flow"}),"\n",(0,s.jsx)(n.p,{children:"To keep things simple in the initial version:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature engineering jobs"})," wrote raw outputs to an ",(0,s.jsx)(n.strong,{children:"S3 bucket"})]}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.strong,{children:"daily feature push job"}),":","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Read from S3"}),"\n",(0,s.jsxs)(n.li,{children:["Grouped related features into ",(0,s.jsx)(n.strong,{children:"Feature Groups"})," (ensuring consistency)"]}),"\n",(0,s.jsxs)(n.li,{children:["Pushed them to ",(0,s.jsx)(n.strong,{children:"Kafka"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"For features requiring frequent updates:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Ad-hoc jobs"})," computed features in higher frequency"]}),"\n",(0,s.jsxs)(n.li,{children:["These jobs pushed to both ",(0,s.jsx)(n.strong,{children:"Kafka"})," and ",(0,s.jsx)(n.strong,{children:"S3"})," (S3 preserved historical data for future model training)"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"the-challenges-data-format-and-storage",children:"The Challenges: Data Format and Storage"}),"\n",(0,s.jsxs)(n.p,{children:["One of the most critical design challenges was how to store feature data ",(0,s.jsx)(n.strong,{children:"efficiently and consistently"}),", especially in databases like ",(0,s.jsx)(n.strong,{children:"Cassandra"})," and ",(0,s.jsx)(n.strong,{children:"Redis"}),", which come with unique storage constraints."]}),"\n",(0,s.jsx)(n.p,{children:"We had to solve for three key requirements:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"feature-consistency",children:"Feature Consistency"}),"\n",(0,s.jsxs)(n.p,{children:["When a feature group contains features like ",(0,s.jsx)(n.code,{children:"order_count_1h"})," and ",(0,s.jsx)(n.code,{children:"click_count_1h"}),", both must reflect the ",(0,s.jsx)(n.strong,{children:"same time window"}),". Inconsistent updates would lead to ",(0,s.jsx)(n.strong,{children:"unreliable model predictions"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"ttl-granularity",children:"TTL Granularity"}),"\n",(0,s.jsxs)(n.p,{children:["Each feature group required an ",(0,s.jsx)(n.strong,{children:"expiry timestamp"}),", so that ",(0,s.jsx)(n.strong,{children:"all features within it expired together"}),"\u2014preserving consistency during reads."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"extensibility-across-databases",children:"Extensibility Across Databases"}),"\n",(0,s.jsxs)(n.p,{children:["We anticipated that infra needs would evolve. To future-proof our system, the data format was designed to be ",(0,s.jsx)(n.strong,{children:"decoupled from DB-specific layouts"}),", enabling portability to systems like ",(0,s.jsx)(n.strong,{children:"ScyllaDB"}),", ",(0,s.jsx)(n.strong,{children:"DynamoDB"}),", ",(0,s.jsx)(n.strong,{children:"HBase"}),", or ",(0,s.jsx)(n.strong,{children:"BigTable"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"overcoming-technical-constraints",children:"Overcoming Technical Constraints"}),"\n",(0,s.jsx)(n.p,{children:'At the time, we were using Cassandra, which not only imposed a soft limit of 75 columns per row, but also exhibited significant performance degradation as the number of columns increased further, particularly in memory constrained machines. Wide rows caused high memory usage during reads, unpredictable latencies due to heavy deserialization overhead, and inefficiencies during compactions and repairs. This ruled out the naive "one column per feature" approach. We needed a format that was compact, minimized the number of columns, and remained efficient and portable across different storage systems.'}),"\n",(0,s.jsx)(n.h2,{id:"the-solution-schema-separation",children:"The Solution: Schema Separation"}),"\n",(0,s.jsx)(n.p,{children:"We introduced the concept of Feature Groups\u2014logical groupings of features that must remain consistent with one another.\nTo represent these groups efficiently, we adopted a layered storage approach:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature Labels (Keys)"})," were stored in ZooKeeper, serving as the schema."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feature Values"})," were stored as a comma-separated string array in Cassandra or Redis."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Expiry Timestamp and Schema Version"})," were appended using a semi-colon delimiter at the end of the string."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"feature_1_value,feature_2_value,feature_3_value;expiry_ts\n"})}),"\n",(0,s.jsx)(n.p,{children:"This format allowed:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Consistent writes and reads at the group level"}),"\n",(0,s.jsx)(n.li,{children:"Easy parsing of feature values using the schema lookup from ZooKeeper"}),"\n",(0,s.jsx)(n.li,{children:"Efficient storage with minimal DB column usage"}),"\n",(0,s.jsx)(n.li,{children:"Support for per-group TTLs and schema evolution"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"tracking-changes-in-feature-groups",children:"Tracking Changes in Feature Groups"}),"\n",(0,s.jsx)(n.p,{children:"Feature groups don\u2019t stay static. As models evolve, features get added, renamed, or removed. But schema changes often go live before the data is ready\u2014and stopping ingestion just to wait for everything to align isn't feasible."}),"\n",(0,s.jsx)(n.h3,{id:"common-real-world-scenarios",children:"Common Real-World Scenarios:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"A new feature is added to the schema, but ingestion jobs still use the older schema version."}),"\n",(0,s.jsx)(n.li,{children:"Ongoing writes don\u2019t include the newly added feature, and stopping ingestion would break freshness for existing features."}),"\n",(0,s.jsx)(n.li,{children:"During serving, models request a mix of old and new features, depending on rollout stages."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"the-solution-schema-versioning",children:"The Solution: Schema Versioning"}),"\n",(0,s.jsx)(n.p,{children:"We solved this with versioned feature group schemas, which unlocked several capabilities:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"backward-compatibility",children:"Backward Compatibility"}),"\n","Older ingestion jobs can continue writing using older schema versions. During reads, the system uses the schema version embedded in the value to interpret the data correctly."]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"partial-availability-handling",children:"Partial Availability Handling"}),"\n","During inference, if some features in the request aren\u2019t available (due to rollout delays or missing data), the system serves default values, ensuring the inference call doesn\u2019t fail."]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.h3,{id:"safe-writes-without-pipeline-pauses",children:"Safe Writes Without Pipeline Pauses"}),"\n","With schema versioning, we no longer had to stop ingestion pipelines for schema updates. Writes using previous versions can continue safely, and downstream consumers evolve independently.\nThis design gave us the flexibility to move fast without breaking things\u2014preserving data quality, enabling experimentation, and ensuring reliability at scale."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(8733).A+"",width:"1600",height:"599"})}),"\n",(0,s.jsx)(n.h2,{id:"interaction-store---0th-version",children:"Interaction Store - 0th Version"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt Text",src:i(395).A+"",width:"1600",height:"518"})}),"\n",(0,s.jsxs)(n.p,{children:["To power real-time Candidate Generators (CGs), we needed fast access to user behavior signals\u2014like what a user recently clicked, ordered, or added to their cart. These interactions form the basis for many real-time recommendations, such as ",(0,s.jsx)(n.strong,{children:"Similar Products"}),", ",(0,s.jsx)(n.strong,{children:"People Also Viewed"}),", or ",(0,s.jsx)(n.strong,{children:"Recently Ordered Again"}),".\nFor the ",(0,s.jsx)(n.strong,{children:"0th version"})," of the Interaction Store, we focused on a design that was ",(0,s.jsx)(n.strong,{children:"simple, fast, and reliable"})," \u2014 optimized for high-throughput ingestion and low-latency lookups."]}),"\n",(0,s.jsx)(n.h2,{id:"event-ingestion",children:"Event Ingestion"}),"\n",(0,s.jsx)(n.p,{children:"We instrumented our backend services to emit key user interaction events to Kafka in real time. These included:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Click"}),"\n",(0,s.jsx)(n.li,{children:"Order"}),"\n",(0,s.jsx)(n.li,{children:"Add to Cart"}),"\n",(0,s.jsx)(n.li,{children:"Wishlist"}),"\n",(0,s.jsx)(n.li,{children:"Share"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Each event carried essential metadata:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"userId \u2014 uniquely identifies the user"}),"\n",(0,s.jsx)(n.li,{children:"productId \u2014 the item being interacted with"}),"\n",(0,s.jsx)(n.li,{children:"timestamp \u2014 the moment the interaction occurred"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This decoupled the interaction logging from storage, allowing ingestion and consumption to scale independently."}),"\n",(0,s.jsx)(n.h2,{id:"storage-design",children:"Storage Design"}),"\n",(0,s.jsx)(n.p,{children:"To store these events, we built Kafka consumers that processed the incoming streams and wrote the data into Redis, using sorted sets (ZSETs) as the primary data structure."}),"\n",(0,s.jsx)(n.h3,{id:"why-redis",children:"Why Redis?"}),"\n",(0,s.jsx)(n.p,{children:"Redis gave us:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Low-latency"})," reads and writes"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Time-ordered data"})," using ZSETs (via score = timestamp)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Native TTL support"}),", if needed in later versions"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"In-memory performance"})," \u2014ideal for real-time CGs"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"storage-structure",children:"Storage Structure"}),"\n",(0,s.jsx)(n.p,{children:"Each user\u2019s interactions were stored using a composite key format, uniquely identifying the user and interaction type. This structure allowed efficient organization and quick retrieval of recent activity for recommendation generation:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"userId_eventType \u2192 ZSET[...(pid, ts)...]\n"})}),"\n",(0,s.jsx)(n.p,{children:"Within each ZSET:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"timestamp"})," served as the score, maintaining temporal order"]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"productId"})," (optionally with metadata) was the ",(0,s.jsx)(n.strong,{children:"value"})]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This allowed us to efficiently retrieve the interactions with HTTP-based API server with two query modes:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Fetch the ",(0,s.jsx)(n.strong,{children:"last k interactions"})," of a specific type for a given user with ",(0,s.jsx)(n.code,{children:"ZREVRANGE(userId_eventType, count)"})]}),"\n",(0,s.jsxs)(n.li,{children:["Retrieve ",(0,s.jsx)(n.strong,{children:"all interactions within a time range"})," (e.g., last 24 hours) with ",(0,s.jsx)(n.code,{children:"ZREVRANGEBYSCORE(userId_eventType, timeRange)"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"built-in-guardrails",children:"Built-in Guardrails"}),"\n",(0,s.jsx)(n.p,{children:"Since Redis was the sole store, we implemented High Availability (HA) to prevent data loss. To optimize memory usage, we also enforced size limits per event type\u2014only storing the last k interactions per user, with older entries getting truncated."}),"\n",(0,s.jsx)(n.h2,{id:"conclusion-laying-the-foundation-for-real-time-ml",children:"Conclusion: Laying the Foundation for Real-Time ML"}),"\n",(0,s.jsxs)(n.p,{children:["In this first phase, we tackled the ",(0,s.jsx)(n.strong,{children:"fundamentals"}),"\u2014shifting from batch-based recommendations to a ",(0,s.jsx)(n.strong,{children:"real-time Recommendation"})," using ML platform that could keep up with Meesho\u2019s growth."]}),"\n",(0,s.jsxs)(n.p,{children:["With the ",(0,s.jsx)(n.strong,{children:"IOP Framework"}),", ",(0,s.jsx)(n.strong,{children:"Online Feature Store"}),", and ",(0,s.jsx)(n.strong,{children:"Interaction Store"}),", we built the core infrastructure to support real-time personalization at scale. These wins have already unlocked:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"\u2705 Faster, more dynamic recommendations for millions of users."}),"\n",(0,s.jsx)(n.li,{children:"\u2705 Better infrastructure efficiency, reducing wasted compute power."}),"\n",(0,s.jsx)(n.li,{children:"\u2705 A flexible, modular system that allows for further experimentation."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["But this is just the beginning. While we've solved key challenges, ",(0,s.jsx)(n.strong,{children:"certain roadblocks remain"})," \u2014from optimizing ",(0,s.jsx)(n.strong,{children:"cost-performance trade-offs"})," to ",(0,s.jsx)(n.strong,{children:"seamlessly evolving schemas"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This foundational work laid the path for a reliable and scalable ",(0,s.jsx)(n.strong,{children:"real-time feature serving layer"}),"."]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},395:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/interaction-store-v0-68167b64c6e462ef2f177f0f86d55bda.png"},1164:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/bms-7399e8796d2cd24617c432518ce3f312.png"},1757:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/old-batch-arch-bc2cedbc1fed0fc6f08479ba8fe52996.png"},3983:e=>{e.exports=JSON.parse('{"permalink":"/BharatMLStack/blog/post-one","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-one/index.md","source":"@site/blog/bharatmlstack-history/post-one/index.md","title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","description":"BharatMLStack","date":"2022-11-15T00:00:00.000Z","tags":[{"inline":true,"label":"online-feature-store","permalink":"/BharatMLStack/blog/tags/online-feature-store"},{"inline":true,"label":"interaction-store","permalink":"/BharatMLStack/blog/tags/interaction-store"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"}],"readingTime":10.25,"hasTruncateMarker":false,"authors":[{"name":"Adarsha Das","title":"Senior Architect @ Meesho","url":"https://github.com/a0d00kc","imageURL":"https://github.com/a0d00kc.png","key":"adarsha","page":null},{"name":"Aditya Kumar","title":"Lead Software Engineer @ Meesho","url":"https://github.com/Adit2607","imageURL":"https://github.com/Adit2607.png","key":"aditya","page":null},{"name":"Bhawani Singh","title":"Architect @ Meesho","url":"https://github.com/singh-bhawani","imageURL":"https://github.com/singh-bhawani.png","key":"bhawani","page":null},{"name":"Jigar Dave","title":"Lead Software Engineer @ Meesho","url":"https://github.com/jigarpatel26","imageURL":"https://github.com/jigarpatel26.png","key":"jigar","page":null}],"frontMatter":{"slug":"post-one","title":"Building Meesho\u2019s ML Platform: From Chaos to Cutting-Edge (Part 1)","authors":["adarsha","aditya","bhawani","jigar"],"date":"2022-11-15T00:00:00.000Z","tags":["online-feature-store","interaction-store","mlplatform","meesho"]},"unlisted":false,"prevItem":{"title":"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)","permalink":"/BharatMLStack/blog/post-two"}}')},5017:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/online-feature-store-v0-86ec0010947ae24621f39ebd0d1729ca.png"},7848:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/first-gen-arch-7c0b286810aecb7eff42b48f51caee1f.png"},8453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>o});var t=i(6540);const s={},r=t.createContext(s);function a(e){const n=t.useContext(r);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(r.Provider,{value:n},e.children)}},8733:(e,n,i)=>{i.d(n,{A:()=>t});const t=i.p+"assets/images/schema-d699efc400ed0f83bba421c1f55ab211.png"}}]); \ No newline at end of file diff --git a/docs/assets/js/f9755c6e.8811662b.js b/docs/assets/js/f9755c6e.8811662b.js new file mode 100644 index 00000000..d17be1e7 --- /dev/null +++ b/docs/assets/js/f9755c6e.8811662b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8315],{5969:e=>{e.exports=JSON.parse('{"permalink":"/BharatMLStack/blog/post-five","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-five/index.md","source":"@site/blog/bharatmlstack-history/post-five/index.md","title":"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale","description":"BharatMLStack","date":"2025-06-02T00:00:00.000Z","tags":[{"inline":true,"label":"llm","permalink":"/BharatMLStack/blog/tags/llm"},{"inline":true,"label":"vllm","permalink":"/BharatMLStack/blog/tags/vllm"},{"inline":true,"label":"tensorrt-llm","permalink":"/BharatMLStack/blog/tags/tensorrt-llm"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"},{"inline":true,"label":"bharatmlstack","permalink":"/BharatMLStack/blog/tags/bharatmlstack"}],"readingTime":4.93,"hasTruncateMarker":false,"authors":[{"name":"Jaya Kumar","title":"Lead ML Engineer @ Meesho","url":"https://github.com/jayakommuru","imageURL":"https://github.com/jayakommuru.png","key":"jaya","page":null}],"frontMatter":{"slug":"post-five","title":"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale","authors":["jaya"],"date":"2025-6-2","tags":["llm","vllm","tensorrt-llm","mlplatform","meesho","bharatmlstack"]},"unlisted":false,"nextItem":{"title":"Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving","permalink":"/BharatMLStack/blog/post-three"}}')},8319:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>h,contentTitle:()=>d,default:()=>o,frontMatter:()=>r,metadata:()=>n,toc:()=>c});var n=i(5969),s=i(4848),l=i(8453);const r={slug:"post-five",title:"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale",authors:["jaya"],date:"2025-6-2",tags:["llm","vllm","tensorrt-llm","mlplatform","meesho","bharatmlstack"]},d=void 0,h={authorsImageUrls:[void 0]},c=[{value:"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale",id:"llm-inference-optimization-techniques-engineering-sub-second-latency-at-scale",level:2},{value:"1. Advanced Memory Management: Paged & Prefix KV Caching",id:"1-advanced-memory-management-paged--prefix-kv-caching",level:2},{value:"Paged KV caching",id:"paged-kv-caching",level:3},{value:"KV cache quantization",id:"kv-cache-quantization",level:3},{value:"Prefix caching (the "voice bot" optimizer)",id:"prefix-caching-the-voice-bot-optimizer",level:3},{value:"2. Aggressive Quantization (INT4 AWQ & FP8)",id:"2-aggressive-quantization-int4-awq--fp8",level:2},{value:"INT4 AWQ (Activation-aware Weight Quantization)",id:"int4-awq-activation-aware-weight-quantization",level:3},{value:"FP8 precision",id:"fp8-precision",level:3},{value:"3. Kernel Fusion & Custom Plugins",id:"3-kernel-fusion--custom-plugins",level:2},{value:"4. Inflight (Continuous) Batching",id:"4-inflight-continuous-batching",level:2},{value:"5. Parallelism Strategies: Scaling Beyond One GPU",id:"5-parallelism-strategies-scaling-beyond-one-gpu",level:2},{value:"6. Speculative Decoding",id:"6-speculative-decoding",level:2},{value:"Few Benchmarks",id:"few-benchmarks",level:2},{value:"Search query rewriting",id:"search-query-rewriting",level:3},{value:"Voice bot query",id:"voice-bot-query",level:3},{value:"Conclusion",id:"conclusion",level:2}];function a(e){const t={h2:"h2",h3:"h3",img:"img",li:"li",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,l.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"BharatMLStack",src:i(9200).A+"",width:"1396",height:"460"})}),"\n",(0,s.jsx)(t.h2,{id:"llm-inference-optimization-techniques-engineering-sub-second-latency-at-scale",children:"LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale"}),"\n",(0,s.jsx)(t.p,{children:"Raw execution of Large Language Models is inherently expensive and memory-intensive. To achieve sub-second latency and high throughput, we implement a multi-layered optimization strategy that targets the entire inference stack\u2014from memory management to kernel execution."}),"\n",(0,s.jsx)(t.h2,{id:"1-advanced-memory-management-paged--prefix-kv-caching",children:"1. Advanced Memory Management: Paged & Prefix KV Caching"}),"\n",(0,s.jsx)(t.p,{children:"The most significant bottleneck in LLM inference is not always compute, but memory bandwidth\u2014specifically managing the Key-Value (KV) cache."}),"\n",(0,s.jsx)(t.h3,{id:"paged-kv-caching",children:"Paged KV caching"}),"\n",(0,s.jsxs)(t.p,{children:["Standard caching suffers from fragmentation. We use ",(0,s.jsx)(t.strong,{children:"Paged KV caching"}),", which operates similarly to an operating system's virtual memory: the KV cache is divided into non-contiguous blocks. This lets us serve larger batch sizes without running out of memory."]}),"\n",(0,s.jsx)(t.h3,{id:"kv-cache-quantization",children:"KV cache quantization"}),"\n",(0,s.jsxs)(t.p,{children:["To further maximize available memory, we implement ",(0,s.jsx)(t.strong,{children:"KV cache quantization"})," (e.g., FP8). By compressing stored attention keys and values from 16-bit to 8-bit, we nearly double the effective context window capacity of the GPU, allowing longer conversations or larger batches without materially degrading quality."]}),"\n",(0,s.jsx)(t.h3,{id:"prefix-caching-the-voice-bot-optimizer",children:'Prefix caching (the "voice bot" optimizer)'}),"\n",(0,s.jsxs)(t.p,{children:['For use cases like GenAI voice bots where the system prompt (e.g., "You are a helpful assistant...") is static across thousands of requests, we enable ',(0,s.jsx)(t.strong,{children:"prefix caching"}),"."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Impact"}),": By reusing pre-computed KV states for common prefixes, we achieve a cache hit rate of ~90%. This reduces ",(0,s.jsx)(t.strong,{children:"Time To First Token (TTFT)"})," by skipping redundant computation of the system prompt."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"2-aggressive-quantization-int4-awq--fp8",children:"2. Aggressive Quantization (INT4 AWQ & FP8)"}),"\n",(0,s.jsx)(t.p,{children:"Running models in their native 16-bit precision (BF16) restricts maximum batch size and throughput. We use quantization to shrink model weights without sacrificing accuracy."}),"\n",(0,s.jsx)(t.h3,{id:"int4-awq-activation-aware-weight-quantization",children:"INT4 AWQ (Activation-aware Weight Quantization)"}),"\n",(0,s.jsxs)(t.p,{children:["For the Llama 3 family, we use ",(0,s.jsx)(t.strong,{children:"AWQ"})," to compress weights to 4 bits. This reduces model size by ~75%, allowing larger models to fit into L4 GPU memory and significantly improving token generation speed."]}),"\n",(0,s.jsx)(t.h3,{id:"fp8-precision",children:"FP8 precision"}),"\n",(0,s.jsxs)(t.p,{children:["For NVIDIA Hopper (H100) architectures, we are exploring ",(0,s.jsx)(t.strong,{children:"FP8 quantization"}),", leveraging native FP8 tensor cores to accelerate matrix multiplications while maintaining a higher dynamic range than integer quantization."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Verification"}),": We validate quantized models by comparing dot-product similarity of embeddings against the FP16 baseline, consistently achieving ",(0,s.jsx)(t.strong,{children:">99% similarity"}),"."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"3-kernel-fusion--custom-plugins",children:"3. Kernel Fusion & Custom Plugins"}),"\n",(0,s.jsx)(t.p,{children:"To minimize overhead from launching thousands of small GPU operations, we fuse them into monolithic kernels using NVIDIA TensorRT plugins."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Flash attention & FMHA"}),": We enable ",(0,s.jsx)(t.strong,{children:"Fused Multi-Head Attention (FMHA)"})," combined with flash attention to reduce memory reads/writes."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"GEMM plugins"}),": We use specialized ",(0,s.jsx)(t.strong,{children:"GEMM"})," plugins to accelerate transformer linear layers."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Removing input padding"}),": Instead of padding short sequences to match the longest, we remove input padding so the GPU processes only valid tokens."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"4-inflight-continuous-batching",children:"4. Inflight (Continuous) Batching"}),"\n",(0,s.jsx)(t.p,{children:"Traditional static batching waits for all requests in a batch to finish before returning results\u2014so one long response delays everyone else."}),"\n",(0,s.jsxs)(t.p,{children:["We implement ",(0,s.jsx)(t.strong,{children:"inflight batching"}),": as soon as one request completes, its slot is freed and filled by a new request from the queue. This keeps GPUs saturated and decouples latency of short queries from long ones."]}),"\n",(0,s.jsx)(t.h2,{id:"5-parallelism-strategies-scaling-beyond-one-gpu",children:"5. Parallelism Strategies: Scaling Beyond One GPU"}),"\n",(0,s.jsx)(t.p,{children:"For large models (e.g., 70B+ parameters) that cannot fit into the VRAM of a single GPU, we use parallelism strategies."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Tensor parallelism (TP)"}),": Split weight matrices across multiple GPUs (e.g., 4\xd7 L4 or 8\xd7 A100). Each GPU computes a shard and outputs are reduced at every layer."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Pipeline parallelism (PP)"}),": Split model layers across GPUs to pipeline compute (e.g., while one GPU computes later layers for Request A, another starts early layers for Request B)."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"6-speculative-decoding",children:"6. Speculative Decoding"}),"\n",(0,s.jsxs)(t.p,{children:["To reduce inter-token latency (ITL), we explore ",(0,s.jsx)(t.strong,{children:"speculative decoding"}),"."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Mechanism"}),': A smaller, faster "draft" model speculatively generates a short token sequence (e.g., 5 tokens).']}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Verification"}),": The larger target model verifies those tokens in one parallel forward pass. If correct, we effectively generate multiple tokens per large-model step; if not, we discard and regenerate. This is effective for predictable text, improving perceived generation speed."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"few-benchmarks",children:"Few Benchmarks"}),"\n",(0,s.jsx)(t.p,{children:"Below are a couple of representative use cases and performance numbers."}),"\n",(0,s.jsx)(t.h3,{id:"search-query-rewriting",children:"Search query rewriting"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"LLM"}),": Fine-tuned llama-3.2-1B"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Input & output token length"}),": ~10\u201320"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Response type"}),": Non-streaming"]}),"\n"]}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Inference runtime"}),(0,s.jsx)(t.th,{children:"Hardware"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Max requests/sec"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Max p99 latency"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{children:"4 \xd7 L4 GPUs (multi-GPU)"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1000"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"95 ms"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{children:"1 \xd7 A100 40 GB GPU"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1000"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"69 ms"})]})]})]}),"\n",(0,s.jsx)(t.h3,{id:"voice-bot-query",children:"Voice bot query"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"LLM"}),": Llama-3.1-8B"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Input token length"}),": ~1900\u20132000"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Output token length"}),": ~200"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Response type"}),": Streaming"]}),"\n"]}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Inference runtime"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Concurrency"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"p99 TTFT (ms)"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"p99 ITL (ms)"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Token throughput (tokens/sec)"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Request throughput (req/sec)"}),(0,s.jsx)(t.th,{children:"Hardware"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"36.27"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"22.78"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"45.66"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"0.23"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"2"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"49.81"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"23.21"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"89.37"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"0.45"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"4"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"55.33"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"36.62"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"153.39"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"0.78"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"8"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"66.5"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"39.11"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"279.88"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1.47"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"16"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"131.8"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"30.39"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"547.8"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"2.77"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"32"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"277.22"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"48.02"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"925.7"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"4.78"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"64"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"498.52"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"71.62"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1,164.40"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"6.2"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"128"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"677.31"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"120.37"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1,445.18"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"7.69"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"256"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1,926.31"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"216.88"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1,600.81"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"8.52"}),(0,s.jsx)(t.td,{children:"L4"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"21.17"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"9.24"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"130.05"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"0.68"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"2"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"25.78"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"9.21"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"264.5"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1.35"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"4"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"28.52"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"10.99"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"437.69"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"2.27"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"8"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"34.4"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"12.61"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"760.49"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"3.96"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"16"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"68.03"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"14.32"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"1,343.80"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"7.01"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"32"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"185.96"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"16.82"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"2,287.30"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"11.92"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"64"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"136.87"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"21.17"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"3,625.22"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"18.89"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"128"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"463.78"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"34.15"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"4,456.51"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"23.24"}),(0,s.jsx)(t.td,{children:"A100"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TensorRT-LLM"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"256"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"890.12"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"59.18"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"5,188.24"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:"27.05"}),(0,s.jsx)(t.td,{children:"A100"})]})]})]}),"\n",(0,s.jsx)(t.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,s.jsx)(t.p,{children:"High-performance LLM inference is fundamentally a systems engineering problem: memory efficiency, kernel execution, batching strategy, and parallelism determine real-world latency and throughput. Techniques such as paged KV caching, aggressive quantization, kernel fusion, and inflight batching improve GPU utilization while reducing latency and memory pressure."}),"\n",(0,s.jsx)(t.p,{children:"These optimizations enable the platform to deliver sub-second responses, sustain high concurrency, and efficiently serve both lightweight and long-context workloads. By continuously optimizing across the full inference stack, we keep LLM serving scalable, cost-efficient, and production-ready for real-time AI applications."})]})}function o(e={}){const{wrapper:t}={...(0,l.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},8453:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>d});var n=i(6540);const s={},l=n.createContext(s);function r(e){const t=n.useContext(l);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(l.Provider,{value:t},e.children)}},9200:(e,t,i)=>{i.d(t,{A:()=>n});const n=i.p+"assets/images/bms-7399e8796d2cd24617c432518ce3f312.png"}}]); \ No newline at end of file diff --git a/docs/assets/js/f994c8da.90063f83.js b/docs/assets/js/f994c8da.256af20d.js similarity index 75% rename from docs/assets/js/f994c8da.90063f83.js rename to docs/assets/js/f994c8da.256af20d.js index d977a51a..a3f70d59 100644 --- a/docs/assets/js/f994c8da.90063f83.js +++ b/docs/assets/js/f994c8da.256af20d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1999],{38:a=>{a.exports=JSON.parse('{"metadata":{"permalink":"/BharatMLStack/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1999],{38:a=>{a.exports=JSON.parse('{"metadata":{"permalink":"/BharatMLStack/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":5,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/fa31f022.968b3373.js b/docs/assets/js/fa31f022.968b3373.js new file mode 100644 index 00000000..fa441b0d --- /dev/null +++ b/docs/assets/js/fa31f022.968b3373.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6062],{6096:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"v1.0.0","description":"Numerix v1.0.0","slug":"/category/v100","permalink":"/BharatMLStack/category/v100","sidebar":"tutorialSidebar","navigation":{"previous":{"title":"Python SDK","permalink":"/BharatMLStack/category/python-sdk"},"next":{"title":"GRPC Feature client","permalink":"/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/fa31f022.c62034f4.js b/docs/assets/js/fa31f022.c62034f4.js deleted file mode 100644 index 7ca34e55..00000000 --- a/docs/assets/js/fa31f022.c62034f4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6062],{6096:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"v1.0.0","description":"Python SDK v1.0.0 documentation for BharatML Stack. Contains API reference, usage guides, and examples for the Python client libraries including gRPC feature client, Spark feature push client, and common utilities.","slug":"/category/v100","permalink":"/BharatMLStack/category/v100","sidebar":"tutorialSidebar","navigation":{"previous":{"title":"Python SDK","permalink":"/BharatMLStack/category/python-sdk"},"next":{"title":"GRPC Feature client","permalink":"/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/fccc4c42.4690f84a.js b/docs/assets/js/fccc4c42.4690f84a.js new file mode 100644 index 00000000..539fe26f --- /dev/null +++ b/docs/assets/js/fccc4c42.4690f84a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2117],{702:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/vss-c482f6eac4c68b3219e4c562a6b717ec.png"},788:e=>{e.exports=JSON.parse('{"permalink":"/BharatMLStack/blog/post-three","editUrl":"https://github.com/Meesho/BharatMLStack/tree/main/docs/blog/bharatmlstack-history/post-three/index.md","source":"@site/blog/bharatmlstack-history/post-three/index.md","title":"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search","description":"BharatMLStack","date":"2024-05-21T00:00:00.000Z","tags":[{"inline":true,"label":"model-inference","permalink":"/BharatMLStack/blog/tags/model-inference"},{"inline":true,"label":"embedding-search","permalink":"/BharatMLStack/blog/tags/embedding-search"},{"inline":true,"label":"mlplatform","permalink":"/BharatMLStack/blog/tags/mlplatform"},{"inline":true,"label":"meesho","permalink":"/BharatMLStack/blog/tags/meesho"},{"inline":true,"label":"bharatmlstack","permalink":"/BharatMLStack/blog/tags/bharatmlstack"}],"readingTime":3.6,"hasTruncateMarker":false,"authors":[{"name":"Aditya Kumar","title":"Lead Software Engineer @ Meesho","url":"https://github.com/Adit2607","imageURL":"https://github.com/Adit2607.png","key":"aditya","page":null},{"name":"Jaya Kumar","title":"Lead ML Engineer @ Meesho","url":"https://github.com/jayakommuru","imageURL":"https://github.com/jayakommuru.png","key":"jaya","page":null},{"name":"Adarsha Das","title":"Senior Architect @ Meesho","url":"https://github.com/a0d00kc","imageURL":"https://github.com/a0d00kc.png","key":"adarsha","page":null}],"frontMatter":{"slug":"post-three","title":"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search","authors":["aditya","jaya","adarsha"],"date":"2024-05-21T00:00:00.000Z","tags":["model-inference","embedding-search","mlplatform","meesho","bharatmlstack"]},"unlisted":false,"prevItem":{"title":"Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving","permalink":"/BharatMLStack/blog/post-three"},"nextItem":{"title":"Building Meesho\u2019s ML Platform: Lessons from the First-Gen System (Part 2)","permalink":"/BharatMLStack/blog/post-two"}}')},2561:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>d});var i=t(788),a=t(4848),r=t(8453);const s={slug:"post-three",title:"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search",authors:["aditya","jaya","adarsha"],date:new Date("2024-05-21T00:00:00.000Z"),tags:["model-inference","embedding-search","mlplatform","meesho","bharatmlstack"]},l=void 0,o={authorsImageUrls:[void 0,void 0,void 0]},d=[{value:"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search",id:"cracking-the-code-scaling-model-inference--real-time-embedding-search",level:2},{value:"Breaking Free from the Scalability Ceiling",id:"breaking-free-from-the-scalability-ceiling",level:2},{value:"The Model Serving Bottleneck\u2014A Wake-Up Call",id:"the-model-serving-bottlenecka-wake-up-call",level:3},{value:"Scaling Triton on GKE",id:"scaling-triton-on-gke",level:3},{value:"Fixing the Cold Start Problem",id:"fixing-the-cold-start-problem",level:3},{value:"Embedding Search: The Last Piece of the Puzzle",id:"embedding-search-the-last-piece-of-the-puzzle",level:2},{value:"Choosing the Right Vector Database",id:"choosing-the-right-vector-database",level:3},{value:"Embedding Freshness & Real-Time Updates",id:"embedding-freshness--real-time-updates",level:3},{value:"Final Takeaways: Scaling Smartly for Real-Time ML",id:"final-takeaways-scaling-smartly-for-real-time-ml",level:2}];function c(e){const n={h2:"h2",h3:"h3",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"BharatMLStack",src:t(6e3).A+"",width:"1396",height:"460"})}),"\n",(0,a.jsx)(n.h2,{id:"cracking-the-code-scaling-model-inference--real-time-embedding-search",children:"Cracking the Code: Scaling Model Inference & Real-Time Embedding Search"}),"\n",(0,a.jsx)(n.p,{children:"By mid-2023, we had transformed our ML stack\u2014building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\ud83d\udd39 Scaling model inference without hitting infrastructure roadblocks"}),"\n",(0,a.jsx)(n.li,{children:"\ud83d\udd39 Moving embedding search from batch to real-time for candidate generation"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Here\u2019s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system."}),"\n",(0,a.jsx)(n.h2,{id:"breaking-free-from-the-scalability-ceiling",children:"Breaking Free from the Scalability Ceiling"}),"\n",(0,a.jsx)(n.h3,{id:"the-model-serving-bottlenecka-wake-up-call",children:"The Model Serving Bottleneck\u2014A Wake-Up Call"}),"\n",(0,a.jsx)(n.p,{children:"July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue\u2014scaling our model-serving infrastructure was taking 10\u201315 minutes. In real-time ML, that\u2019s an eternity.\nIn one of our war rooms, we ran a quick experiment:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\ud83d\ude80 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine."}),"\n",(0,a.jsx)(n.li,{children:"\ud83d\ude80 Fired requests and compared the outputs with our existing cloud-hosted setup."}),"\n",(0,a.jsx)(n.li,{children:"\ud83d\ude80 The results matched\u2014perfectly."}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:'That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn\'t allocate enough compute resources in time. Luckily, they did\u2014but the seed was planted.\nThen in October, just two weeks before MBS, we got an alarming response from our infrastructure team:\n"Node availability may be an issue."\nWith no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?'}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\u2705 p99 latency dropped from 90\u2013100ms to 30\u201340ms"}),"\n",(0,a.jsx)(n.li,{children:"\u2705 Triton handled significantly higher throughput on fewer resources"}),"\n",(0,a.jsx)(n.li,{children:"\u2705 No model changes were needed"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"MBS ran without a hitch, proving that self-hosted inference was the way forward."}),"\n",(0,a.jsx)(n.h3,{id:"scaling-triton-on-gke",children:"Scaling Triton on GKE"}),"\n",(0,a.jsx)(n.p,{children:"This left us with two choices:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"1\ufe0f\u20e3 Port models to a managed cloud inference service, investing time in learning a new deployment stack"}),"\n",(0,a.jsx)(n.li,{children:"2\ufe0f\u20e3 Scale our existing Triton setup on GKE, optimizing for cost and performance"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"We went with Option 2\u2014and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations."}),"\n",(0,a.jsx)(n.h3,{id:"fixing-the-cold-start-problem",children:"Fixing the Cold Start Problem"}),"\n",(0,a.jsx)(n.p,{children:"As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7\u20139 minutes to spin up."}),"\n",(0,a.jsx)(n.p,{children:"After profiling, we found the culprits:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Triton\u2019s base image\u2014a massive 5GB"}),"\n",(0,a.jsx)(n.li,{children:"Model binaries\u2014often 1GB+"}),"\n",(0,a.jsx)(n.li,{children:"Startup delay\u2014mostly due to downloading and initializing these assets"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother."}),"\n",(0,a.jsx)(n.h2,{id:"embedding-search-the-last-piece-of-the-puzzle",children:"Embedding Search: The Last Piece of the Puzzle"}),"\n",(0,a.jsx)(n.p,{children:"By mid-2023, most of our ML stack had gone real-time\u2014except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system."}),"\n",(0,a.jsx)(n.h3,{id:"choosing-the-right-vector-database",children:"Choosing the Right Vector Database"}),"\n",(0,a.jsx)(n.p,{children:"We benchmarked three production-ready vector DBs across key parameters:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Milvus"}),"\n",(0,a.jsx)(n.li,{children:"Qdrant"}),"\n",(0,a.jsx)(n.li,{children:"Weaviate"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"After extensive POCs, Qdrant stood out for its:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\u2705 Blazing-fast search latency on high-dimensional vectors"}),"\n",(0,a.jsx)(n.li,{children:"\u2705 Efficient memory usage, crucial for in-memory workloads"}),"\n",(0,a.jsx)(n.li,{children:"\u2705 Support for upserts and soft deletes, vital for Ads use cases"}),"\n",(0,a.jsx)(n.li,{children:"\u2705 gRPC + REST APIs, making integration seamless"}),"\n",(0,a.jsx)(n.li,{children:"\u2705 Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search\u2014a perfect fit for our needs."}),"\n",(0,a.jsx)(n.h3,{id:"embedding-freshness--real-time-updates",children:"Embedding Freshness & Real-Time Updates"}),"\n",(0,a.jsx)(n.p,{children:"To ensure embeddings stayed up to date, we built a dual ingestion pipeline:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\ud83d\udccc Daily Refresh: A bulk pipeline updated embeddings overnight"}),"\n",(0,a.jsx)(n.li,{children:"\ud83d\udccc Real-Time Updates: Ads events triggered immediate upserts/deletes"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:'This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.'}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"Skye",src:t(702).A+"",width:"1260",height:"644"})}),"\n",(0,a.jsx)(n.h2,{id:"final-takeaways-scaling-smartly-for-real-time-ml",children:"Final Takeaways: Scaling Smartly for Real-Time ML"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\ud83d\ude80 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services"}),"\n",(0,a.jsx)(n.li,{children:"\ud83d\ude80 Building a custom Triton image reduced cold starts, improving responsiveness"}),"\n",(0,a.jsx)(n.li,{children:"\ud83d\ude80 Qdrant-based embedding search enabled real-time personalization at scale"}),"\n",(0,a.jsx)(n.li,{children:"\ud83d\ude80 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"By early 2024, Meesho\u2019s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},6e3:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/bms-7399e8796d2cd24617c432518ce3f312.png"},8453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>l});var i=t(6540);const a={},r=i.createContext(a);function s(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/main.3e15e71d.js b/docs/assets/js/main.3e15e71d.js new file mode 100644 index 00000000..1a92bb08 --- /dev/null +++ b/docs/assets/js/main.3e15e71d.js @@ -0,0 +1,2 @@ +/*! For license information please see main.3e15e71d.js.LICENSE.txt */ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8792],{115:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,a="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function o(e,i){if(e===i)return!0;if(e&&i&&"object"==typeof e&&"object"==typeof i){if(e.constructor!==i.constructor)return!1;var l,s,c,u;if(Array.isArray(e)){if((l=e.length)!=i.length)return!1;for(s=l;0!==s--;)if(!o(e[s],i[s]))return!1;return!0}if(n&&e instanceof Map&&i instanceof Map){if(e.size!==i.size)return!1;for(u=e.entries();!(s=u.next()).done;)if(!i.has(s.value[0]))return!1;for(u=e.entries();!(s=u.next()).done;)if(!o(s.value[1],i.get(s.value[0])))return!1;return!0}if(r&&e instanceof Set&&i instanceof Set){if(e.size!==i.size)return!1;for(u=e.entries();!(s=u.next()).done;)if(!i.has(s.value[0]))return!1;return!0}if(a&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(i)){if((l=e.length)!=i.length)return!1;for(s=l;0!==s--;)if(e[s]!==i[s])return!1;return!0}if(e.constructor===RegExp)return e.source===i.source&&e.flags===i.flags;if(e.valueOf!==Object.prototype.valueOf&&"function"==typeof e.valueOf&&"function"==typeof i.valueOf)return e.valueOf()===i.valueOf();if(e.toString!==Object.prototype.toString&&"function"==typeof e.toString&&"function"==typeof i.toString)return e.toString()===i.toString();if((l=(c=Object.keys(e)).length)!==Object.keys(i).length)return!1;for(s=l;0!==s--;)if(!Object.prototype.hasOwnProperty.call(i,c[s]))return!1;if(t&&e instanceof Element)return!1;for(s=l;0!==s--;)if(("_owner"!==c[s]&&"__v"!==c[s]&&"__o"!==c[s]||!e.$$typeof)&&!o(e[c[s]],i[c[s]]))return!1;return!0}return e!=e&&i!=i}e.exports=function(e,t){try{return o(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},119:(e,t,n)=>{"use strict";n.r(t)},205:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(6540);const a=n(8193).A.canUseDOM?r.useLayoutEffect:r.useEffect},253:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=function e(t){if(t.cause)return[t,...e(t.cause)];return[t]}},311:e=>{"use strict";e.exports=function(e,t,n,r,a,o,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,i,l],u=0;(s=new Error(t.replace(/%s/g,function(){return c[u++]}))).name="Invariant Violation"}throw s.framesToPop=1,s}}},418:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});const r=()=>null},440:(e,t,n)=>{"use strict";t.rA=t.Ks=t.LU=void 0;const r=n(1635);t.LU="__blog-post-container";var a=n(2983);Object.defineProperty(t,"Ks",{enumerable:!0,get:function(){return r.__importDefault(a).default}});var o=n(2566);var i=n(253);Object.defineProperty(t,"rA",{enumerable:!0,get:function(){return i.getErrorCausalChain}})},545:(e,t,n)=>{"use strict";n.d(t,{mg:()=>J,vd:()=>G});var r=n(6540),a=n(5556),o=n.n(a),i=n(115),l=n.n(i),s=n(311),c=n.n(s),u=n(2833),d=n.n(u);function f(){return f=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},f.apply(this,arguments)}function p(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,h(e,t)}function h(e,t){return h=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},h(e,t)}function m(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)t.indexOf(n=o[r])>=0||(a[n]=e[n]);return a}var g={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},b={rel:["amphtml","canonical","alternate"]},y={type:["application/ld+json"]},v={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},w=Object.keys(g).map(function(e){return g[e]}),k={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},S=Object.keys(k).reduce(function(e,t){return e[k[t]]=t,e},{}),x=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},_=function(e){var t=x(e,g.TITLE),n=x(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,function(){return t});var r=x(e,"defaultTitle");return t||r||void 0},E=function(e){return x(e,"onChangeClientState")||function(){}},C=function(e,t){return t.filter(function(t){return void 0!==t[e]}).map(function(t){return t[e]}).reduce(function(e,t){return f({},e,t)},{})},A=function(e,t){return t.filter(function(e){return void 0!==e[g.BASE]}).map(function(e){return e[g.BASE]}).reverse().reduce(function(t,n){if(!t.length)for(var r=Object.keys(n),a=0;a<r.length;a+=1){var o=r[a].toLowerCase();if(-1!==e.indexOf(o)&&n[o])return t.concat(n)}return t},[])},L=function(e,t,n){var r={};return n.filter(function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)}).map(function(t){return t[e]}).reverse().reduce(function(e,n){var a={};n.filter(function(e){for(var n,o=Object.keys(e),i=0;i<o.length;i+=1){var l=o[i],s=l.toLowerCase();-1===t.indexOf(s)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===s&&"stylesheet"===e[s].toLowerCase()||(n=s),-1===t.indexOf(l)||"innerHTML"!==l&&"cssText"!==l&&"itemprop"!==l||(n=l)}if(!n||!e[n])return!1;var c=e[n].toLowerCase();return r[n]||(r[n]={}),a[n]||(a[n]={}),!r[n][c]&&(a[n][c]=!0,!0)}).reverse().forEach(function(t){return e.push(t)});for(var o=Object.keys(a),i=0;i<o.length;i+=1){var l=o[i],s=f({},r[l],a[l]);r[l]=s}return e},[]).reverse()},T=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},j=function(e){return Array.isArray(e)?e.join(""):e},P=function(e,t){return Array.isArray(e)?e.reduce(function(e,n){return function(e,t){for(var n=Object.keys(e),r=0;r<n.length;r+=1)if(t[n[r]]&&t[n[r]].includes(e[n[r]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e},{priority:[],default:[]}):{default:e}},M=function(e,t){var n;return f({},e,((n={})[t]=void 0,n))},N=[g.NOSCRIPT,g.SCRIPT,g.STYLE],O=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},R=function(e){return Object.keys(e).reduce(function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r},"")},D=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce(function(t,n){return t[k[n]||n]=e[n],t},t)},B=function(e,t){return t.map(function(t,n){var a,o=((a={key:n})["data-rh"]=!0,a);return Object.keys(t).forEach(function(e){var n=k[e]||e;"innerHTML"===n||"cssText"===n?o.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:o[n]=t[e]}),r.createElement(e,o)})},F=function(e,t,n){switch(e){case g.TITLE:return{toComponent:function(){return n=t.titleAttributes,(a={key:e=t.title})["data-rh"]=!0,o=D(n,a),[r.createElement(g.TITLE,o,e)];var e,n,a,o},toString:function(){return function(e,t,n,r){var a=R(n),o=j(t);return a?"<"+e+' data-rh="true" '+a+">"+O(o,r)+"</"+e+">":"<"+e+' data-rh="true">'+O(o,r)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return D(t)},toString:function(){return R(t)}};default:return{toComponent:function(){return B(e,t)},toString:function(){return function(e,t,n){return t.reduce(function(t,r){var a=Object.keys(r).filter(function(e){return!("innerHTML"===e||"cssText"===e)}).reduce(function(e,t){var a=void 0===r[t]?t:t+'="'+O(r[t],n)+'"';return e?e+" "+a:a},""),o=r.innerHTML||r.cssText||"",i=-1===N.indexOf(e);return t+"<"+e+' data-rh="true" '+a+(i?"/>":">"+o+"</"+e+">")},"")}(e,t,n)}}}},I=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,a=e.htmlAttributes,o=e.noscriptTags,i=e.styleTags,l=e.title,s=void 0===l?"":l,c=e.titleAttributes,u=e.linkTags,d=e.metaTags,f=e.scriptTags,p={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var h=function(e){var t=e.linkTags,n=e.scriptTags,r=e.encode,a=P(e.metaTags,v),o=P(t,b),i=P(n,y);return{priorityMethods:{toComponent:function(){return[].concat(B(g.META,a.priority),B(g.LINK,o.priority),B(g.SCRIPT,i.priority))},toString:function(){return F(g.META,a.priority,r)+" "+F(g.LINK,o.priority,r)+" "+F(g.SCRIPT,i.priority,r)}},metaTags:a.default,linkTags:o.default,scriptTags:i.default}}(e);p=h.priorityMethods,u=h.linkTags,d=h.metaTags,f=h.scriptTags}return{priority:p,base:F(g.BASE,t,r),bodyAttributes:F("bodyAttributes",n,r),htmlAttributes:F("htmlAttributes",a,r),link:F(g.LINK,u,r),meta:F(g.META,d,r),noscript:F(g.NOSCRIPT,o,r),script:F(g.SCRIPT,f,r),style:F(g.STYLE,i,r),title:F(g.TITLE,{title:s,titleAttributes:c},r)}},z=[],$=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?z:n.instances},add:function(e){(n.canUseDOM?z:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?z:n.instances).indexOf(e);(n.canUseDOM?z:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=I({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},U=r.createContext({}),q=o().shape({setHelmet:o().func,helmetInstances:o().shape({get:o().func,add:o().func,remove:o().func})}),H="undefined"!=typeof document,G=function(e){function t(n){var r;return(r=e.call(this,n)||this).helmetData=new $(r.props.context,t.canUseDOM),r}return p(t,e),t.prototype.render=function(){return r.createElement(U.Provider,{value:this.helmetData.value},this.props.children)},t}(r.Component);G.canUseDOM=H,G.propTypes={context:o().shape({helmet:o().shape()}),children:o().node.isRequired},G.defaultProps={context:{}},G.displayName="HelmetProvider";var V=function(e,t){var n,r=document.head||document.querySelector(g.HEAD),a=r.querySelectorAll(e+"[data-rh]"),o=[].slice.call(a),i=[];return t&&t.length&&t.forEach(function(t){var r=document.createElement(e);for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&("innerHTML"===a?r.innerHTML=t.innerHTML:"cssText"===a?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(a,void 0===t[a]?"":t[a]));r.setAttribute("data-rh","true"),o.some(function(e,t){return n=t,r.isEqualNode(e)})?o.splice(n,1):i.push(r)}),o.forEach(function(e){return e.parentNode.removeChild(e)}),i.forEach(function(e){return r.appendChild(e)}),{oldTags:o,newTags:i}},W=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),a=r?r.split(","):[],o=[].concat(a),i=Object.keys(t),l=0;l<i.length;l+=1){var s=i[l],c=t[s]||"";n.getAttribute(s)!==c&&n.setAttribute(s,c),-1===a.indexOf(s)&&a.push(s);var u=o.indexOf(s);-1!==u&&o.splice(u,1)}for(var d=o.length-1;d>=0;d-=1)n.removeAttribute(o[d]);a.length===o.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==i.join(",")&&n.setAttribute("data-rh",i.join(","))}},Q=function(e,t){var n=e.baseTag,r=e.htmlAttributes,a=e.linkTags,o=e.metaTags,i=e.noscriptTags,l=e.onChangeClientState,s=e.scriptTags,c=e.styleTags,u=e.title,d=e.titleAttributes;W(g.BODY,e.bodyAttributes),W(g.HTML,r),function(e,t){void 0!==e&&document.title!==e&&(document.title=j(e)),W(g.TITLE,t)}(u,d);var f={baseTag:V(g.BASE,n),linkTags:V(g.LINK,a),metaTags:V(g.META,o),noscriptTags:V(g.NOSCRIPT,i),scriptTags:V(g.SCRIPT,s),styleTags:V(g.STYLE,c)},p={},h={};Object.keys(f).forEach(function(e){var t=f[e],n=t.newTags,r=t.oldTags;n.length&&(p[e]=n),r.length&&(h[e]=f[e].oldTags)}),t&&t(),l(e,p,h)},K=null,Y=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(t=e.call.apply(e,[this].concat(r))||this).rendered=!1,t}p(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!d()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,r=n.setHelmet,a=null,o=(e=n.helmetInstances.get().map(function(e){var t=f({},e.props);return delete t.context,t}),{baseTag:A(["href"],e),bodyAttributes:C("bodyAttributes",e),defer:x(e,"defer"),encode:x(e,"encodeSpecialCharacters"),htmlAttributes:C("htmlAttributes",e),linkTags:L(g.LINK,["rel","href"],e),metaTags:L(g.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:L(g.NOSCRIPT,["innerHTML"],e),onChangeClientState:E(e),scriptTags:L(g.SCRIPT,["src","innerHTML"],e),styleTags:L(g.STYLE,["cssText"],e),title:_(e),titleAttributes:C("titleAttributes",e),prioritizeSeoTags:T(e,"prioritizeSeoTags")});G.canUseDOM?(t=o,K&&cancelAnimationFrame(K),t.defer?K=requestAnimationFrame(function(){Q(t,function(){K=null})}):(Q(t),K=null)):I&&(a=I(o)),r(a)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(r.Component);Y.propTypes={context:q.isRequired},Y.displayName="HelmetDispatcher";var X=["children"],Z=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}p(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!l()(M(this.props,"helmetData"),M(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case g.SCRIPT:case g.NOSCRIPT:return{innerHTML:t};case g.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return f({},r,((t={})[n.type]=[].concat(r[n.type]||[],[f({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,a=e.newProps,o=e.newChildProps,i=e.nestedChildren;switch(r.type){case g.TITLE:return f({},a,((t={})[r.type]=i,t.titleAttributes=f({},o),t));case g.BODY:return f({},a,{bodyAttributes:f({},o)});case g.HTML:return f({},a,{htmlAttributes:f({},o)});default:return f({},a,((n={})[r.type]=f({},o),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=f({},t);return Object.keys(e).forEach(function(t){var r;n=f({},n,((r={})[t]=e[t],r))}),n},n.warnOnInvalidChildren=function(e,t){return c()(w.some(function(t){return e.type===t}),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+w.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),c()(!t||"string"==typeof t||Array.isArray(t)&&!t.some(function(e){return"string"!=typeof e}),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,a={};return r.Children.forEach(e,function(e){if(e&&e.props){var r=e.props,o=r.children,i=m(r,X),l=Object.keys(i).reduce(function(e,t){return e[S[t]||t]=i[t],e},{}),s=e.type;switch("symbol"==typeof s?s=s.toString():n.warnOnInvalidChildren(e,o),s){case g.FRAGMENT:t=n.mapChildrenToProps(o,t);break;case g.LINK:case g.META:case g.NOSCRIPT:case g.SCRIPT:case g.STYLE:a=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:a,newChildProps:l,nestedChildren:o});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:l,nestedChildren:o})}}}),this.mapArrayTypeChildrenToProps(a,t)},n.render=function(){var e=this.props,t=e.children,n=m(e,Z),a=f({},n),o=n.helmetData;return t&&(a=this.mapChildrenToProps(t,a)),!o||o instanceof $||(o=new $(o.context,o.instances)),o?r.createElement(Y,f({},a,{context:o.value,helmetData:void 0})):r.createElement(U.Consumer,null,function(e){return r.createElement(Y,f({},a,{context:e}))})},t}(r.Component);J.propTypes={base:o().object,bodyAttributes:o().object,children:o().oneOfType([o().arrayOf(o().node),o().node]),defaultTitle:o().string,defer:o().bool,encodeSpecialCharacters:o().bool,htmlAttributes:o().object,link:o().arrayOf(o().object),meta:o().arrayOf(o().object),noscript:o().arrayOf(o().object),onChangeClientState:o().func,script:o().arrayOf(o().object),style:o().arrayOf(o().object),title:o().string,titleAttributes:o().object,titleTemplate:o().string,prioritizeSeoTags:o().bool,helmetData:o().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},609:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,t:()=>c});var r=n(6540),a=n(9532),o=n(4848);const i=Symbol("EmptyContext"),l=r.createContext(i);function s({children:e,name:t,items:n}){const a=(0,r.useMemo)(()=>t&&n?{name:t,items:n}:null,[t,n]);return(0,o.jsx)(l.Provider,{value:a,children:e})}function c(){const e=(0,r.useContext)(l);if(e===i)throw new a.dV("DocsSidebarProvider");return e}},679:(e,t,n)=>{"use strict";n.d(t,{Wf:()=>c});n(6540);const r=JSON.parse('{"N":"localStorage","M":""}'),a=r.N;function o({key:e,oldValue:t,newValue:n,storage:r}){if(t===n)return;const a=document.createEvent("StorageEvent");a.initStorageEvent("storage",!1,!1,e,t,n,window.location.href,r),window.dispatchEvent(a)}function i(e=a){if("undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,l||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),l=!0),null}var t}let l=!1;const s={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function c(e,t){const n=`${e}${r.M}`;if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(n);const a=i(t?.persistence);return null===a?s:{get:()=>{try{return a.getItem(n)}catch(e){return console.error(`Docusaurus storage error, can't get key=${n}`,e),null}},set:e=>{try{const t=a.getItem(n);a.setItem(n,e),o({key:n,oldValue:t,newValue:e,storage:a})}catch(t){console.error(`Docusaurus storage error, can't set ${n}=${e}`,t)}},del:()=>{try{const e=a.getItem(n);a.removeItem(n),o({key:n,oldValue:e,newValue:null,storage:a})}catch(e){console.error(`Docusaurus storage error, can't delete key=${n}`,e)}},listen:e=>{try{const t=t=>{t.storageArea===a&&t.key===n&&e(t)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)}catch(t){return console.error(`Docusaurus storage error, can't listen for changes of key=${n}`,t),()=>{}}}}}},961:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(6221)},1043:(e,t,n)=>{"use strict";n.r(t)},1107:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(6540);var r=n(4164),a=n(1312),o=n(6342),i=n(8774),l=n(3427);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var c=n(4848);function u({as:e,id:t,...n}){const u=(0,l.A)(),{navbar:{hideOnScroll:d}}=(0,o.p)();if("h1"===e||!t)return(0,c.jsx)(e,{...n,id:void 0});u.collectAnchor(t);const f=(0,a.T)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof n.children?n.children:t});return(0,c.jsxs)(e,{...n,className:(0,r.A)("anchor",d?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,n.className),id:t,children:[n.children,(0,c.jsx)(i.A,{className:"hash-link",to:`#${t}`,"aria-label":f,title:f,children:"\u200b"})]})}},1122:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});var r=n(6540),a=n(4164),o=n(2303),i=n(5293);const l={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var s=n(4848);function c({className:e,children:t}){const n=(0,o.A)(),{colorMode:c}=(0,i.G)();return(0,s.jsx)(s.Fragment,{children:(n?"dark"===c?["dark"]:["light"]:["light","dark"]).map(n=>{const o=t({theme:n,className:(0,a.A)(e,l.themedComponent,l[`themedComponent--${n}`])});return(0,s.jsx)(r.Fragment,{children:o},n)})})}function u(e){const{sources:t,className:n,alt:r,...a}=e;return(0,s.jsx)(c,{className:n,children:({theme:e,className:n})=>(0,s.jsx)("img",{src:t[e],alt:r,className:n,...a})})}},1247:(e,t,n)=>{"use strict";var r=n(9982),a=n(6540),o=n(961);function i(e){var t="https://react.dev/errors/"+e;if(1<arguments.length){t+="?args[]="+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n])}return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}function l(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType)}function s(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{!!(4098&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function c(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function u(e){if(s(e)!==e)throw Error(i(188))}function d(e){var t=e.tag;if(5===t||26===t||27===t||6===t)return e;for(e=e.child;null!==e;){if(null!==(t=d(e)))return t;e=e.sibling}return null}var f=Object.assign,p=Symbol.for("react.element"),h=Symbol.for("react.transitional.element"),m=Symbol.for("react.portal"),g=Symbol.for("react.fragment"),b=Symbol.for("react.strict_mode"),y=Symbol.for("react.profiler"),v=Symbol.for("react.provider"),w=Symbol.for("react.consumer"),k=Symbol.for("react.context"),S=Symbol.for("react.forward_ref"),x=Symbol.for("react.suspense"),_=Symbol.for("react.suspense_list"),E=Symbol.for("react.memo"),C=Symbol.for("react.lazy");Symbol.for("react.scope");var A=Symbol.for("react.activity");Symbol.for("react.legacy_hidden"),Symbol.for("react.tracing_marker");var L=Symbol.for("react.memo_cache_sentinel");Symbol.for("react.view_transition");var T=Symbol.iterator;function j(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=T&&e[T]||e["@@iterator"])?e:null}var P=Symbol.for("react.client.reference");function M(e){if(null==e)return null;if("function"==typeof e)return e.$$typeof===P?null:e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case g:return"Fragment";case y:return"Profiler";case b:return"StrictMode";case x:return"Suspense";case _:return"SuspenseList";case A:return"Activity"}if("object"==typeof e)switch(e.$$typeof){case m:return"Portal";case k:return(e.displayName||"Context")+".Provider";case w:return(e._context.displayName||"Context")+".Consumer";case S:var t=e.render;return(e=e.displayName)||(e=""!==(e=t.displayName||t.name||"")?"ForwardRef("+e+")":"ForwardRef"),e;case E:return null!==(t=e.displayName||null)?t:M(e.type)||"Memo";case C:t=e._payload,e=e._init;try{return M(e(t))}catch(n){}}return null}var N=Array.isArray,O=a.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,R=o.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,D={pending:!1,data:null,method:null,action:null},B=[],F=-1;function I(e){return{current:e}}function z(e){0>F||(e.current=B[F],B[F]=null,F--)}function $(e,t){F++,B[F]=e.current,e.current=t}var U=I(null),q=I(null),H=I(null),G=I(null);function V(e,t){switch($(H,t),$(q,e),$(U,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?ad(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)e=od(t=ad(t),e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}z(U),$(U,e)}function W(){z(U),z(q),z(H)}function Q(e){null!==e.memoizedState&&$(G,e);var t=U.current,n=od(t,e.type);t!==n&&($(q,e),$(U,n))}function K(e){q.current===e&&(z(U),z(q)),G.current===e&&(z(G),Qd._currentValue=D)}var Y=Object.prototype.hasOwnProperty,X=r.unstable_scheduleCallback,Z=r.unstable_cancelCallback,J=r.unstable_shouldYield,ee=r.unstable_requestPaint,te=r.unstable_now,ne=r.unstable_getCurrentPriorityLevel,re=r.unstable_ImmediatePriority,ae=r.unstable_UserBlockingPriority,oe=r.unstable_NormalPriority,ie=r.unstable_LowPriority,le=r.unstable_IdlePriority,se=r.log,ce=r.unstable_setDisableYieldValue,ue=null,de=null;function fe(e){if("function"==typeof se&&ce(e),de&&"function"==typeof de.setStrictMode)try{de.setStrictMode(ue,e)}catch(t){}}var pe=Math.clz32?Math.clz32:function(e){return 0===(e>>>=0)?32:31-(he(e)/me|0)|0},he=Math.log,me=Math.LN2;var ge=256,be=4194304;function ye(e){var t=42&e;if(0!==t)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return 4194048&e;case 4194304:case 8388608:case 16777216:case 33554432:return 62914560&e;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function ve(e,t,n){var r=e.pendingLanes;if(0===r)return 0;var a=0,o=e.suspendedLanes,i=e.pingedLanes;e=e.warmLanes;var l=134217727&r;return 0!==l?0!==(r=l&~o)?a=ye(r):0!==(i&=l)?a=ye(i):n||0!==(n=l&~e)&&(a=ye(n)):0!==(l=r&~o)?a=ye(l):0!==i?a=ye(i):n||0!==(n=r&~e)&&(a=ye(n)),0===a?0:0!==t&&t!==a&&0===(t&o)&&((o=a&-a)>=(n=t&-t)||32===o&&4194048&n)?t:a}function we(e,t){return 0===(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)}function ke(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;default:return-1}}function Se(){var e=ge;return!(4194048&(ge<<=1))&&(ge=256),e}function xe(){var e=be;return!(62914560&(be<<=1))&&(be=4194304),e}function _e(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Ee(e,t){e.pendingLanes|=t,268435456!==t&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Ce(e,t,n){e.pendingLanes|=t,e.suspendedLanes&=~t;var r=31-pe(t);e.entangledLanes|=t,e.entanglements[r]=1073741824|e.entanglements[r]|4194090&n}function Ae(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var r=31-pe(n),a=1<<r;a&t|e[r]&t&&(e[r]|=t),n&=~a}}function Le(e){switch(e){case 2:e=1;break;case 8:e=4;break;case 32:e=16;break;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:e=128;break;case 268435456:e=134217728;break;default:e=0}return e}function Te(e){return 2<(e&=-e)?8<e?134217727&e?32:268435456:8:2}function je(){var e=R.p;return 0!==e?e:void 0===(e=window.event)?32:uf(e.type)}var Pe=Math.random().toString(36).slice(2),Me="__reactFiber$"+Pe,Ne="__reactProps$"+Pe,Oe="__reactContainer$"+Pe,Re="__reactEvents$"+Pe,De="__reactListeners$"+Pe,Be="__reactHandles$"+Pe,Fe="__reactResources$"+Pe,Ie="__reactMarker$"+Pe;function ze(e){delete e[Me],delete e[Ne],delete e[Re],delete e[De],delete e[Be]}function $e(e){var t=e[Me];if(t)return t;for(var n=e.parentNode;n;){if(t=n[Oe]||n[Me]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=vd(e);null!==e;){if(n=e[Me])return n;e=vd(e)}return t}n=(e=n).parentNode}return null}function Ue(e){if(e=e[Me]||e[Oe]){var t=e.tag;if(5===t||6===t||13===t||26===t||27===t||3===t)return e}return null}function qe(e){var t=e.tag;if(5===t||26===t||27===t||6===t)return e.stateNode;throw Error(i(33))}function He(e){var t=e[Fe];return t||(t=e[Fe]={hoistableStyles:new Map,hoistableScripts:new Map}),t}function Ge(e){e[Ie]=!0}var Ve=new Set,We={};function Qe(e,t){Ke(e,t),Ke(e+"Capture",t)}function Ke(e,t){for(We[e]=t,e=0;e<t.length;e++)Ve.add(t[e])}var Ye,Xe,Ze=RegExp("^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$"),Je={},et={};function tt(e,t,n){if(a=t,Y.call(et,a)||!Y.call(Je,a)&&(Ze.test(a)?et[a]=!0:(Je[a]=!0,0)))if(null===n)e.removeAttribute(t);else{switch(typeof n){case"undefined":case"function":case"symbol":return void e.removeAttribute(t);case"boolean":var r=t.toLowerCase().slice(0,5);if("data-"!==r&&"aria-"!==r)return void e.removeAttribute(t)}e.setAttribute(t,""+n)}var a}function nt(e,t,n){if(null===n)e.removeAttribute(t);else{switch(typeof n){case"undefined":case"function":case"symbol":case"boolean":return void e.removeAttribute(t)}e.setAttribute(t,""+n)}}function rt(e,t,n,r){if(null===r)e.removeAttribute(n);else{switch(typeof r){case"undefined":case"function":case"symbol":case"boolean":return void e.removeAttribute(n)}e.setAttributeNS(t,n,""+r)}}function at(e){if(void 0===Ye)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);Ye=t&&t[1]||"",Xe=-1<n.stack.indexOf("\n at")?" (<anonymous>)":-1<n.stack.indexOf("@")?"@unknown:0:0":""}return"\n"+Ye+e+Xe}var ot=!1;function it(e,t){if(!e||ot)return"";ot=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var r={DetermineComponentFrameRoot:function(){try{if(t){var n=function(){throw Error()};if(Object.defineProperty(n.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(n,[])}catch(a){var r=a}Reflect.construct(e,[],n)}else{try{n.call()}catch(o){r=o}e.call(n.prototype)}}else{try{throw Error()}catch(i){r=i}(n=e())&&"function"==typeof n.catch&&n.catch(function(){})}}catch(l){if(l&&r&&"string"==typeof l.stack)return[l.stack,r.stack]}return[null,null]}};r.DetermineComponentFrameRoot.displayName="DetermineComponentFrameRoot";var a=Object.getOwnPropertyDescriptor(r.DetermineComponentFrameRoot,"name");a&&a.configurable&&Object.defineProperty(r.DetermineComponentFrameRoot,"name",{value:"DetermineComponentFrameRoot"});var o=r.DetermineComponentFrameRoot(),i=o[0],l=o[1];if(i&&l){var s=i.split("\n"),c=l.split("\n");for(a=r=0;r<s.length&&!s[r].includes("DetermineComponentFrameRoot");)r++;for(;a<c.length&&!c[a].includes("DetermineComponentFrameRoot");)a++;if(r===s.length||a===c.length)for(r=s.length-1,a=c.length-1;1<=r&&0<=a&&s[r]!==c[a];)a--;for(;1<=r&&0<=a;r--,a--)if(s[r]!==c[a]){if(1!==r||1!==a)do{if(r--,0>--a||s[r]!==c[a]){var u="\n"+s[r].replace(" at new "," at ");return e.displayName&&u.includes("<anonymous>")&&(u=u.replace("<anonymous>",e.displayName)),u}}while(1<=r&&0<=a);break}}}finally{ot=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:"")?at(n):""}function lt(e){switch(e.tag){case 26:case 27:case 5:return at(e.type);case 16:return at("Lazy");case 13:return at("Suspense");case 19:return at("SuspenseList");case 0:case 15:return it(e.type,!1);case 11:return it(e.type.render,!1);case 1:return it(e.type,!0);case 31:return at("Activity");default:return""}}function st(e){try{var t="";do{t+=lt(e),e=e.return}while(e);return t}catch(n){return"\nError generating stack: "+n.message+"\n"+n.stack}}function ct(e){switch(typeof e){case"bigint":case"boolean":case"number":case"string":case"undefined":case"object":return e;default:return""}}function ut(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function dt(e){e._valueTracker||(e._valueTracker=function(e){var t=ut(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var a=n.get,o=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return a.call(this)},set:function(e){r=""+e,o.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function ft(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=ut(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function pt(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}var ht=/[\n"\\]/g;function mt(e){return e.replace(ht,function(e){return"\\"+e.charCodeAt(0).toString(16)+" "})}function gt(e,t,n,r,a,o,i,l){e.name="",null!=i&&"function"!=typeof i&&"symbol"!=typeof i&&"boolean"!=typeof i?e.type=i:e.removeAttribute("type"),null!=t?"number"===i?(0===t&&""===e.value||e.value!=t)&&(e.value=""+ct(t)):e.value!==""+ct(t)&&(e.value=""+ct(t)):"submit"!==i&&"reset"!==i||e.removeAttribute("value"),null!=t?yt(e,i,ct(t)):null!=n?yt(e,i,ct(n)):null!=r&&e.removeAttribute("value"),null==a&&null!=o&&(e.defaultChecked=!!o),null!=a&&(e.checked=a&&"function"!=typeof a&&"symbol"!=typeof a),null!=l&&"function"!=typeof l&&"symbol"!=typeof l&&"boolean"!=typeof l?e.name=""+ct(l):e.removeAttribute("name")}function bt(e,t,n,r,a,o,i,l){if(null!=o&&"function"!=typeof o&&"symbol"!=typeof o&&"boolean"!=typeof o&&(e.type=o),null!=t||null!=n){if(("submit"===o||"reset"===o)&&null==t)return;n=null!=n?""+ct(n):"",t=null!=t?""+ct(t):n,l||t===e.value||(e.value=t),e.defaultValue=t}r="function"!=typeof(r=null!=r?r:a)&&"symbol"!=typeof r&&!!r,e.checked=l?e.checked:!!r,e.defaultChecked=!!r,null!=i&&"function"!=typeof i&&"symbol"!=typeof i&&"boolean"!=typeof i&&(e.name=i)}function yt(e,t,n){"number"===t&&pt(e.ownerDocument)===e||e.defaultValue===""+n||(e.defaultValue=""+n)}function vt(e,t,n,r){if(e=e.options,t){t={};for(var a=0;a<n.length;a++)t["$"+n[a]]=!0;for(n=0;n<e.length;n++)a=t.hasOwnProperty("$"+e[n].value),e[n].selected!==a&&(e[n].selected=a),a&&r&&(e[n].defaultSelected=!0)}else{for(n=""+ct(n),t=null,a=0;a<e.length;a++){if(e[a].value===n)return e[a].selected=!0,void(r&&(e[a].defaultSelected=!0));null!==t||e[a].disabled||(t=e[a])}null!==t&&(t.selected=!0)}}function wt(e,t,n){null==t||((t=""+ct(t))!==e.value&&(e.value=t),null!=n)?e.defaultValue=null!=n?""+ct(n):"":e.defaultValue!==t&&(e.defaultValue=t)}function kt(e,t,n,r){if(null==t){if(null!=r){if(null!=n)throw Error(i(92));if(N(r)){if(1<r.length)throw Error(i(93));r=r[0]}n=r}null==n&&(n=""),t=n}n=ct(t),e.defaultValue=n,(r=e.textContent)===n&&""!==r&&null!==r&&(e.value=r)}function St(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var xt=new Set("animationIterationCount aspectRatio borderImageOutset borderImageSlice borderImageWidth boxFlex boxFlexGroup boxOrdinalGroup columnCount columns flex flexGrow flexPositive flexShrink flexNegative flexOrder gridArea gridRow gridRowEnd gridRowSpan gridRowStart gridColumn gridColumnEnd gridColumnSpan gridColumnStart fontWeight lineClamp lineHeight opacity order orphans scale tabSize widows zIndex zoom fillOpacity floodOpacity stopOpacity strokeDasharray strokeDashoffset strokeMiterlimit strokeOpacity strokeWidth MozAnimationIterationCount MozBoxFlex MozBoxFlexGroup MozLineClamp msAnimationIterationCount msFlex msZoom msFlexGrow msFlexNegative msFlexOrder msFlexPositive msFlexShrink msGridColumn msGridColumnSpan msGridRow msGridRowSpan WebkitAnimationIterationCount WebkitBoxFlex WebKitBoxFlexGroup WebkitBoxOrdinalGroup WebkitColumnCount WebkitColumns WebkitFlex WebkitFlexGrow WebkitFlexPositive WebkitFlexShrink WebkitLineClamp".split(" "));function _t(e,t,n){var r=0===t.indexOf("--");null==n||"boolean"==typeof n||""===n?r?e.setProperty(t,""):"float"===t?e.cssFloat="":e[t]="":r?e.setProperty(t,n):"number"!=typeof n||0===n||xt.has(t)?"float"===t?e.cssFloat=n:e[t]=(""+n).trim():e[t]=n+"px"}function Et(e,t,n){if(null!=t&&"object"!=typeof t)throw Error(i(62));if(e=e.style,null!=n){for(var r in n)!n.hasOwnProperty(r)||null!=t&&t.hasOwnProperty(r)||(0===r.indexOf("--")?e.setProperty(r,""):"float"===r?e.cssFloat="":e[r]="");for(var a in t)r=t[a],t.hasOwnProperty(a)&&n[a]!==r&&_t(e,a,r)}else for(var o in t)t.hasOwnProperty(o)&&_t(e,o,t[o])}function Ct(e){if(-1===e.indexOf("-"))return!1;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var At=new Map([["acceptCharset","accept-charset"],["htmlFor","for"],["httpEquiv","http-equiv"],["crossOrigin","crossorigin"],["accentHeight","accent-height"],["alignmentBaseline","alignment-baseline"],["arabicForm","arabic-form"],["baselineShift","baseline-shift"],["capHeight","cap-height"],["clipPath","clip-path"],["clipRule","clip-rule"],["colorInterpolation","color-interpolation"],["colorInterpolationFilters","color-interpolation-filters"],["colorProfile","color-profile"],["colorRendering","color-rendering"],["dominantBaseline","dominant-baseline"],["enableBackground","enable-background"],["fillOpacity","fill-opacity"],["fillRule","fill-rule"],["floodColor","flood-color"],["floodOpacity","flood-opacity"],["fontFamily","font-family"],["fontSize","font-size"],["fontSizeAdjust","font-size-adjust"],["fontStretch","font-stretch"],["fontStyle","font-style"],["fontVariant","font-variant"],["fontWeight","font-weight"],["glyphName","glyph-name"],["glyphOrientationHorizontal","glyph-orientation-horizontal"],["glyphOrientationVertical","glyph-orientation-vertical"],["horizAdvX","horiz-adv-x"],["horizOriginX","horiz-origin-x"],["imageRendering","image-rendering"],["letterSpacing","letter-spacing"],["lightingColor","lighting-color"],["markerEnd","marker-end"],["markerMid","marker-mid"],["markerStart","marker-start"],["overlinePosition","overline-position"],["overlineThickness","overline-thickness"],["paintOrder","paint-order"],["panose-1","panose-1"],["pointerEvents","pointer-events"],["renderingIntent","rendering-intent"],["shapeRendering","shape-rendering"],["stopColor","stop-color"],["stopOpacity","stop-opacity"],["strikethroughPosition","strikethrough-position"],["strikethroughThickness","strikethrough-thickness"],["strokeDasharray","stroke-dasharray"],["strokeDashoffset","stroke-dashoffset"],["strokeLinecap","stroke-linecap"],["strokeLinejoin","stroke-linejoin"],["strokeMiterlimit","stroke-miterlimit"],["strokeOpacity","stroke-opacity"],["strokeWidth","stroke-width"],["textAnchor","text-anchor"],["textDecoration","text-decoration"],["textRendering","text-rendering"],["transformOrigin","transform-origin"],["underlinePosition","underline-position"],["underlineThickness","underline-thickness"],["unicodeBidi","unicode-bidi"],["unicodeRange","unicode-range"],["unitsPerEm","units-per-em"],["vAlphabetic","v-alphabetic"],["vHanging","v-hanging"],["vIdeographic","v-ideographic"],["vMathematical","v-mathematical"],["vectorEffect","vector-effect"],["vertAdvY","vert-adv-y"],["vertOriginX","vert-origin-x"],["vertOriginY","vert-origin-y"],["wordSpacing","word-spacing"],["writingMode","writing-mode"],["xmlnsXlink","xmlns:xlink"],["xHeight","x-height"]]),Lt=/^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*:/i;function Tt(e){return Lt.test(""+e)?"javascript:throw new Error('React has blocked a javascript: URL as a security precaution.')":e}var jt=null;function Pt(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var Mt=null,Nt=null;function Ot(e){var t=Ue(e);if(t&&(e=t.stateNode)){var n=e[Ne]||null;e:switch(e=t.stateNode,t.type){case"input":if(gt(e,n.value,n.defaultValue,n.defaultValue,n.checked,n.defaultChecked,n.type,n.name),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll('input[name="'+mt(""+t)+'"][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var a=r[Ne]||null;if(!a)throw Error(i(90));gt(r,a.value,a.defaultValue,a.defaultValue,a.checked,a.defaultChecked,a.type,a.name)}}for(t=0;t<n.length;t++)(r=n[t]).form===e.form&&ft(r)}break e;case"textarea":wt(e,n.value,n.defaultValue);break e;case"select":null!=(t=n.value)&&vt(e,!!n.multiple,t,!1)}}}var Rt=!1;function Dt(e,t,n){if(Rt)return e(t,n);Rt=!0;try{return e(t)}finally{if(Rt=!1,(null!==Mt||null!==Nt)&&($c(),Mt&&(t=Mt,e=Nt,Nt=Mt=null,Ot(t),e)))for(t=0;t<e.length;t++)Ot(e[t])}}function Bt(e,t){var n=e.stateNode;if(null===n)return null;var r=n[Ne]||null;if(null===r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(i(231,t,typeof n));return n}var Ft=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),It=!1;if(Ft)try{var zt={};Object.defineProperty(zt,"passive",{get:function(){It=!0}}),window.addEventListener("test",zt,zt),window.removeEventListener("test",zt,zt)}catch(Of){It=!1}var $t=null,Ut=null,qt=null;function Ht(){if(qt)return qt;var e,t,n=Ut,r=n.length,a="value"in $t?$t.value:$t.textContent,o=a.length;for(e=0;e<r&&n[e]===a[e];e++);var i=r-e;for(t=1;t<=i&&n[r-t]===a[o-t];t++);return qt=a.slice(e,1<t?1-t:void 0)}function Gt(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function Vt(){return!0}function Wt(){return!1}function Qt(e){function t(t,n,r,a,o){for(var i in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=a,this.target=o,this.currentTarget=null,e)e.hasOwnProperty(i)&&(t=e[i],this[i]=t?t(a):a[i]);return this.isDefaultPrevented=(null!=a.defaultPrevented?a.defaultPrevented:!1===a.returnValue)?Vt:Wt,this.isPropagationStopped=Wt,this}return f(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=Vt)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=Vt)},persist:function(){},isPersistent:Vt}),t}var Kt,Yt,Xt,Zt={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},Jt=Qt(Zt),en=f({},Zt,{view:0,detail:0}),tn=Qt(en),nn=f({},en,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:hn,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==Xt&&(Xt&&"mousemove"===e.type?(Kt=e.screenX-Xt.screenX,Yt=e.screenY-Xt.screenY):Yt=Kt=0,Xt=e),Kt)},movementY:function(e){return"movementY"in e?e.movementY:Yt}}),rn=Qt(nn),an=Qt(f({},nn,{dataTransfer:0})),on=Qt(f({},en,{relatedTarget:0})),ln=Qt(f({},Zt,{animationName:0,elapsedTime:0,pseudoElement:0})),sn=Qt(f({},Zt,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}})),cn=Qt(f({},Zt,{data:0})),un={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},dn={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},fn={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function pn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=fn[e])&&!!t[e]}function hn(){return pn}var mn=Qt(f({},en,{key:function(e){if(e.key){var t=un[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=Gt(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?dn[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:hn,charCode:function(e){return"keypress"===e.type?Gt(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?Gt(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}})),gn=Qt(f({},nn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),bn=Qt(f({},en,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:hn})),yn=Qt(f({},Zt,{propertyName:0,elapsedTime:0,pseudoElement:0})),vn=Qt(f({},nn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0})),wn=Qt(f({},Zt,{newState:0,oldState:0})),kn=[9,13,27,32],Sn=Ft&&"CompositionEvent"in window,xn=null;Ft&&"documentMode"in document&&(xn=document.documentMode);var _n=Ft&&"TextEvent"in window&&!xn,En=Ft&&(!Sn||xn&&8<xn&&11>=xn),Cn=String.fromCharCode(32),An=!1;function Ln(e,t){switch(e){case"keyup":return-1!==kn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Tn(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var jn=!1;var Pn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Mn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Pn[e.type]:"textarea"===t}function Nn(e,t,n,r){Mt?Nt?Nt.push(r):Nt=[r]:Mt=r,0<(t=Hu(t,"onChange")).length&&(n=new Jt("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var On=null,Rn=null;function Dn(e){Du(e,0)}function Bn(e){if(ft(qe(e)))return e}function Fn(e,t){if("change"===e)return t}var In=!1;if(Ft){var zn;if(Ft){var $n="oninput"in document;if(!$n){var Un=document.createElement("div");Un.setAttribute("oninput","return;"),$n="function"==typeof Un.oninput}zn=$n}else zn=!1;In=zn&&(!document.documentMode||9<document.documentMode)}function qn(){On&&(On.detachEvent("onpropertychange",Hn),Rn=On=null)}function Hn(e){if("value"===e.propertyName&&Bn(Rn)){var t=[];Nn(t,Rn,e,Pt(e)),Dt(Dn,t)}}function Gn(e,t,n){"focusin"===e?(qn(),Rn=n,(On=t).attachEvent("onpropertychange",Hn)):"focusout"===e&&qn()}function Vn(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Bn(Rn)}function Wn(e,t){if("click"===e)return Bn(t)}function Qn(e,t){if("input"===e||"change"===e)return Bn(t)}var Kn="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t};function Yn(e,t){if(Kn(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++){var a=n[r];if(!Y.call(t,a)||!Kn(e[a],t[a]))return!1}return!0}function Xn(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function Zn(e,t){var n,r=Xn(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=Xn(r)}}function Jn(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?Jn(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function er(e){for(var t=pt((e=null!=e&&null!=e.ownerDocument&&null!=e.ownerDocument.defaultView?e.ownerDocument.defaultView:window).document);t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=pt((e=t.contentWindow).document)}return t}function tr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}var nr=Ft&&"documentMode"in document&&11>=document.documentMode,rr=null,ar=null,or=null,ir=!1;function lr(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;ir||null==rr||rr!==pt(r)||("selectionStart"in(r=rr)&&tr(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},or&&Yn(or,r)||(or=r,0<(r=Hu(ar,"onSelect")).length&&(t=new Jt("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=rr)))}function sr(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var cr={animationend:sr("Animation","AnimationEnd"),animationiteration:sr("Animation","AnimationIteration"),animationstart:sr("Animation","AnimationStart"),transitionrun:sr("Transition","TransitionRun"),transitionstart:sr("Transition","TransitionStart"),transitioncancel:sr("Transition","TransitionCancel"),transitionend:sr("Transition","TransitionEnd")},ur={},dr={};function fr(e){if(ur[e])return ur[e];if(!cr[e])return e;var t,n=cr[e];for(t in n)if(n.hasOwnProperty(t)&&t in dr)return ur[e]=n[t];return e}Ft&&(dr=document.createElement("div").style,"AnimationEvent"in window||(delete cr.animationend.animation,delete cr.animationiteration.animation,delete cr.animationstart.animation),"TransitionEvent"in window||delete cr.transitionend.transition);var pr=fr("animationend"),hr=fr("animationiteration"),mr=fr("animationstart"),gr=fr("transitionrun"),br=fr("transitionstart"),yr=fr("transitioncancel"),vr=fr("transitionend"),wr=new Map,kr="abort auxClick beforeToggle cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Sr(e,t){wr.set(e,t),Qe(t,[e])}kr.push("scrollEnd");var xr=new WeakMap;function _r(e,t){if("object"==typeof e&&null!==e){var n=xr.get(e);return void 0!==n?n:(t={value:e,source:t,stack:st(t)},xr.set(e,t),t)}return{value:e,source:t,stack:st(t)}}var Er=[],Cr=0,Ar=0;function Lr(){for(var e=Cr,t=Ar=Cr=0;t<e;){var n=Er[t];Er[t++]=null;var r=Er[t];Er[t++]=null;var a=Er[t];Er[t++]=null;var o=Er[t];if(Er[t++]=null,null!==r&&null!==a){var i=r.pending;null===i?a.next=a:(a.next=i.next,i.next=a),r.pending=a}0!==o&&Mr(n,a,o)}}function Tr(e,t,n,r){Er[Cr++]=e,Er[Cr++]=t,Er[Cr++]=n,Er[Cr++]=r,Ar|=r,e.lanes|=r,null!==(e=e.alternate)&&(e.lanes|=r)}function jr(e,t,n,r){return Tr(e,t,n,r),Nr(e)}function Pr(e,t){return Tr(e,null,null,t),Nr(e)}function Mr(e,t,n){e.lanes|=n;var r=e.alternate;null!==r&&(r.lanes|=n);for(var a=!1,o=e.return;null!==o;)o.childLanes|=n,null!==(r=o.alternate)&&(r.childLanes|=n),22===o.tag&&(null===(e=o.stateNode)||1&e._visibility||(a=!0)),e=o,o=o.return;return 3===e.tag?(o=e.stateNode,a&&null!==t&&(a=31-pe(n),null===(r=(e=o.hiddenUpdates)[a])?e[a]=[t]:r.push(t),t.lane=536870912|n),o):null}function Nr(e){if(50<Mc)throw Mc=0,Nc=null,Error(i(185));for(var t=e.return;null!==t;)t=(e=t).return;return 3===e.tag?e.stateNode:null}var Or={};function Rr(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.refCleanup=this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Dr(e,t,n,r){return new Rr(e,t,n,r)}function Br(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Fr(e,t){var n=e.alternate;return null===n?((n=Dr(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=65011712&e.flags,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n.refCleanup=e.refCleanup,n}function Ir(e,t){e.flags&=65011714;var n=e.alternate;return null===n?(e.childLanes=0,e.lanes=t,e.child=null,e.subtreeFlags=0,e.memoizedProps=null,e.memoizedState=null,e.updateQueue=null,e.dependencies=null,e.stateNode=null):(e.childLanes=n.childLanes,e.lanes=n.lanes,e.child=n.child,e.subtreeFlags=0,e.deletions=null,e.memoizedProps=n.memoizedProps,e.memoizedState=n.memoizedState,e.updateQueue=n.updateQueue,e.type=n.type,t=n.dependencies,e.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext}),e}function zr(e,t,n,r,a,o){var l=0;if(r=e,"function"==typeof e)Br(e)&&(l=1);else if("string"==typeof e)l=function(e,t,n){if(1===n||null!=t.itemProp)return!1;switch(e){case"meta":case"title":return!0;case"style":if("string"!=typeof t.precedence||"string"!=typeof t.href||""===t.href)break;return!0;case"link":if("string"!=typeof t.rel||"string"!=typeof t.href||""===t.href||t.onLoad||t.onError)break;return"stylesheet"!==t.rel||(e=t.disabled,"string"==typeof t.precedence&&null==e);case"script":if(t.async&&"function"!=typeof t.async&&"symbol"!=typeof t.async&&!t.onLoad&&!t.onError&&t.src&&"string"==typeof t.src)return!0}return!1}(e,n,U.current)?26:"html"===e||"head"===e||"body"===e?27:5;else e:switch(e){case A:return(e=Dr(31,n,t,a)).elementType=A,e.lanes=o,e;case g:return $r(n.children,a,o,t);case b:l=8,a|=24;break;case y:return(e=Dr(12,n,t,2|a)).elementType=y,e.lanes=o,e;case x:return(e=Dr(13,n,t,a)).elementType=x,e.lanes=o,e;case _:return(e=Dr(19,n,t,a)).elementType=_,e.lanes=o,e;default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case v:case k:l=10;break e;case w:l=9;break e;case S:l=11;break e;case E:l=14;break e;case C:l=16,r=null;break e}l=29,n=Error(i(130,null===e?"null":typeof e,"")),r=null}return(t=Dr(l,n,t,a)).elementType=e,t.type=r,t.lanes=o,t}function $r(e,t,n,r){return(e=Dr(7,e,r,t)).lanes=n,e}function Ur(e,t,n){return(e=Dr(6,e,null,t)).lanes=n,e}function qr(e,t,n){return(t=Dr(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}var Hr=[],Gr=0,Vr=null,Wr=0,Qr=[],Kr=0,Yr=null,Xr=1,Zr="";function Jr(e,t){Hr[Gr++]=Wr,Hr[Gr++]=Vr,Vr=e,Wr=t}function ea(e,t,n){Qr[Kr++]=Xr,Qr[Kr++]=Zr,Qr[Kr++]=Yr,Yr=e;var r=Xr;e=Zr;var a=32-pe(r)-1;r&=~(1<<a),n+=1;var o=32-pe(t)+a;if(30<o){var i=a-a%5;o=(r&(1<<i)-1).toString(32),r>>=i,a-=i,Xr=1<<32-pe(t)+a|n<<a|r,Zr=o+e}else Xr=1<<o|n<<a|r,Zr=e}function ta(e){null!==e.return&&(Jr(e,1),ea(e,1,0))}function na(e){for(;e===Vr;)Vr=Hr[--Gr],Hr[Gr]=null,Wr=Hr[--Gr],Hr[Gr]=null;for(;e===Yr;)Yr=Qr[--Kr],Qr[Kr]=null,Zr=Qr[--Kr],Qr[Kr]=null,Xr=Qr[--Kr],Qr[Kr]=null}var ra=null,aa=null,oa=!1,ia=null,la=!1,sa=Error(i(519));function ca(e){throw ma(_r(Error(i(418,"")),e)),sa}function ua(e){var t=e.stateNode,n=e.type,r=e.memoizedProps;switch(t[Me]=e,t[Ne]=r,n){case"dialog":Bu("cancel",t),Bu("close",t);break;case"iframe":case"object":case"embed":Bu("load",t);break;case"video":case"audio":for(n=0;n<Ou.length;n++)Bu(Ou[n],t);break;case"source":Bu("error",t);break;case"img":case"image":case"link":Bu("error",t),Bu("load",t);break;case"details":Bu("toggle",t);break;case"input":Bu("invalid",t),bt(t,r.value,r.defaultValue,r.checked,r.defaultChecked,r.type,r.name,!0),dt(t);break;case"select":Bu("invalid",t);break;case"textarea":Bu("invalid",t),kt(t,r.value,r.defaultValue,r.children),dt(t)}"string"!=typeof(n=r.children)&&"number"!=typeof n&&"bigint"!=typeof n||t.textContent===""+n||!0===r.suppressHydrationWarning||Yu(t.textContent,n)?(null!=r.popover&&(Bu("beforetoggle",t),Bu("toggle",t)),null!=r.onScroll&&Bu("scroll",t),null!=r.onScrollEnd&&Bu("scrollend",t),null!=r.onClick&&(t.onclick=Xu),t=!0):t=!1,t||ca(e)}function da(e){for(ra=e.return;ra;)switch(ra.tag){case 5:case 13:return void(la=!1);case 27:case 3:return void(la=!0);default:ra=ra.return}}function fa(e){if(e!==ra)return!1;if(!oa)return da(e),oa=!0,!1;var t,n=e.tag;if((t=3!==n&&27!==n)&&((t=5===n)&&(t=!("form"!==(t=e.type)&&"button"!==t)||id(e.type,e.memoizedProps)),t=!t),t&&aa&&ca(e),da(e),13===n){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(i(317));e:{for(e=e.nextSibling,n=0;e;){if(8===e.nodeType)if("/$"===(t=e.data)){if(0===n){aa=bd(e.nextSibling);break e}n--}else"$"!==t&&"$!"!==t&&"$?"!==t||n++;e=e.nextSibling}aa=null}}else 27===n?(n=aa,pd(e.type)?(e=yd,yd=null,aa=e):aa=n):aa=ra?bd(e.stateNode.nextSibling):null;return!0}function pa(){aa=ra=null,oa=!1}function ha(){var e=ia;return null!==e&&(null===vc?vc=e:vc.push.apply(vc,e),ia=null),e}function ma(e){null===ia?ia=[e]:ia.push(e)}var ga=I(null),ba=null,ya=null;function va(e,t,n){$(ga,t._currentValue),t._currentValue=n}function wa(e){e._currentValue=ga.current,z(ga)}function ka(e,t,n){for(;null!==e;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,null!==r&&(r.childLanes|=t)):null!==r&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function Sa(e,t,n,r){var a=e.child;for(null!==a&&(a.return=e);null!==a;){var o=a.dependencies;if(null!==o){var l=a.child;o=o.firstContext;e:for(;null!==o;){var s=o;o=a;for(var c=0;c<t.length;c++)if(s.context===t[c]){o.lanes|=n,null!==(s=o.alternate)&&(s.lanes|=n),ka(o.return,n,e),r||(l=null);break e}o=s.next}}else if(18===a.tag){if(null===(l=a.return))throw Error(i(341));l.lanes|=n,null!==(o=l.alternate)&&(o.lanes|=n),ka(l,n,e),l=null}else l=a.child;if(null!==l)l.return=a;else for(l=a;null!==l;){if(l===e){l=null;break}if(null!==(a=l.sibling)){a.return=l.return,l=a;break}l=l.return}a=l}}function xa(e,t,n,r){e=null;for(var a=t,o=!1;null!==a;){if(!o)if(524288&a.flags)o=!0;else if(262144&a.flags)break;if(10===a.tag){var l=a.alternate;if(null===l)throw Error(i(387));if(null!==(l=l.memoizedProps)){var s=a.type;Kn(a.pendingProps.value,l.value)||(null!==e?e.push(s):e=[s])}}else if(a===G.current){if(null===(l=a.alternate))throw Error(i(387));l.memoizedState.memoizedState!==a.memoizedState.memoizedState&&(null!==e?e.push(Qd):e=[Qd])}a=a.return}null!==e&&Sa(t,e,n,r),t.flags|=262144}function _a(e){for(e=e.firstContext;null!==e;){if(!Kn(e.context._currentValue,e.memoizedValue))return!0;e=e.next}return!1}function Ea(e){ba=e,ya=null,null!==(e=e.dependencies)&&(e.firstContext=null)}function Ca(e){return La(ba,e)}function Aa(e,t){return null===ba&&Ea(e),La(e,t)}function La(e,t){var n=t._currentValue;if(t={context:t,memoizedValue:n,next:null},null===ya){if(null===e)throw Error(i(308));ya=t,e.dependencies={lanes:0,firstContext:t},e.flags|=524288}else ya=ya.next=t;return n}var Ta="undefined"!=typeof AbortController?AbortController:function(){var e=[],t=this.signal={aborted:!1,addEventListener:function(t,n){e.push(n)}};this.abort=function(){t.aborted=!0,e.forEach(function(e){return e()})}},ja=r.unstable_scheduleCallback,Pa=r.unstable_NormalPriority,Ma={$$typeof:k,Consumer:null,Provider:null,_currentValue:null,_currentValue2:null,_threadCount:0};function Na(){return{controller:new Ta,data:new Map,refCount:0}}function Oa(e){e.refCount--,0===e.refCount&&ja(Pa,function(){e.controller.abort()})}var Ra=null,Da=0,Ba=0,Fa=null;function Ia(){if(0===--Da&&null!==Ra){null!==Fa&&(Fa.status="fulfilled");var e=Ra;Ra=null,Ba=0,Fa=null;for(var t=0;t<e.length;t++)(0,e[t])()}}var za=O.S;O.S=function(e,t){"object"==typeof t&&null!==t&&"function"==typeof t.then&&function(e,t){if(null===Ra){var n=Ra=[];Da=0,Ba=Tu(),Fa={status:"pending",value:void 0,then:function(e){n.push(e)}}}Da++,t.then(Ia,Ia)}(0,t),null!==za&&za(e,t)};var $a=I(null);function Ua(){var e=$a.current;return null!==e?e:rc.pooledCache}function qa(e,t){$($a,null===t?$a.current:t.pool)}function Ha(){var e=Ua();return null===e?null:{parent:Ma._currentValue,pool:e}}var Ga=Error(i(460)),Va=Error(i(474)),Wa=Error(i(542)),Qa={then:function(){}};function Ka(e){return"fulfilled"===(e=e.status)||"rejected"===e}function Ya(){}function Xa(e,t,n){switch(void 0===(n=e[n])?e.push(t):n!==t&&(t.then(Ya,Ya),t=n),t.status){case"fulfilled":return t.value;case"rejected":throw eo(e=t.reason),e;default:if("string"==typeof t.status)t.then(Ya,Ya);else{if(null!==(e=rc)&&100<e.shellSuspendCounter)throw Error(i(482));(e=t).status="pending",e.then(function(e){if("pending"===t.status){var n=t;n.status="fulfilled",n.value=e}},function(e){if("pending"===t.status){var n=t;n.status="rejected",n.reason=e}})}switch(t.status){case"fulfilled":return t.value;case"rejected":throw eo(e=t.reason),e}throw Za=t,Ga}}var Za=null;function Ja(){if(null===Za)throw Error(i(459));var e=Za;return Za=null,e}function eo(e){if(e===Ga||e===Wa)throw Error(i(483))}var to=!1;function no(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function ro(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function ao(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function oo(e,t,n){var r=e.updateQueue;if(null===r)return null;if(r=r.shared,2&nc){var a=r.pending;return null===a?t.next=t:(t.next=a.next,a.next=t),r.pending=t,t=Nr(e),Mr(e,null,n),t}return Tr(e,r,t,n),Nr(e)}function io(e,t,n){if(null!==(t=t.updateQueue)&&(t=t.shared,4194048&n)){var r=t.lanes;n|=r&=e.pendingLanes,t.lanes=n,Ae(e,n)}}function lo(e,t){var n=e.updateQueue,r=e.alternate;if(null!==r&&n===(r=r.updateQueue)){var a=null,o=null;if(null!==(n=n.firstBaseUpdate)){do{var i={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};null===o?a=o=i:o=o.next=i,n=n.next}while(null!==n);null===o?a=o=t:o=o.next=t}else a=o=t;return n={baseState:r.baseState,firstBaseUpdate:a,lastBaseUpdate:o,shared:r.shared,callbacks:r.callbacks},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var so=!1;function co(){if(so){if(null!==Fa)throw Fa}}function uo(e,t,n,r){so=!1;var a=e.updateQueue;to=!1;var o=a.firstBaseUpdate,i=a.lastBaseUpdate,l=a.shared.pending;if(null!==l){a.shared.pending=null;var s=l,c=s.next;s.next=null,null===i?o=c:i.next=c,i=s;var u=e.alternate;null!==u&&((l=(u=u.updateQueue).lastBaseUpdate)!==i&&(null===l?u.firstBaseUpdate=c:l.next=c,u.lastBaseUpdate=s))}if(null!==o){var d=a.baseState;for(i=0,u=c=s=null,l=o;;){var p=-536870913&l.lane,h=p!==l.lane;if(h?(oc&p)===p:(r&p)===p){0!==p&&p===Ba&&(so=!0),null!==u&&(u=u.next={lane:0,tag:l.tag,payload:l.payload,callback:null,next:null});e:{var m=e,g=l;p=t;var b=n;switch(g.tag){case 1:if("function"==typeof(m=g.payload)){d=m.call(b,d,p);break e}d=m;break e;case 3:m.flags=-65537&m.flags|128;case 0:if(null==(p="function"==typeof(m=g.payload)?m.call(b,d,p):m))break e;d=f({},d,p);break e;case 2:to=!0}}null!==(p=l.callback)&&(e.flags|=64,h&&(e.flags|=8192),null===(h=a.callbacks)?a.callbacks=[p]:h.push(p))}else h={lane:p,tag:l.tag,payload:l.payload,callback:l.callback,next:null},null===u?(c=u=h,s=d):u=u.next=h,i|=p;if(null===(l=l.next)){if(null===(l=a.shared.pending))break;l=(h=l).next,h.next=null,a.lastBaseUpdate=h,a.shared.pending=null}}null===u&&(s=d),a.baseState=s,a.firstBaseUpdate=c,a.lastBaseUpdate=u,null===o&&(a.shared.lanes=0),pc|=i,e.lanes=i,e.memoizedState=d}}function fo(e,t){if("function"!=typeof e)throw Error(i(191,e));e.call(t)}function po(e,t){var n=e.callbacks;if(null!==n)for(e.callbacks=null,e=0;e<n.length;e++)fo(n[e],t)}var ho=I(null),mo=I(0);function go(e,t){$(mo,e=dc),$(ho,t),dc=e|t.baseLanes}function bo(){$(mo,dc),$(ho,ho.current)}function yo(){dc=mo.current,z(ho),z(mo)}var vo=0,wo=null,ko=null,So=null,xo=!1,_o=!1,Eo=!1,Co=0,Ao=0,Lo=null,To=0;function jo(){throw Error(i(321))}function Po(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!Kn(e[n],t[n]))return!1;return!0}function Mo(e,t,n,r,a,o){return vo=o,wo=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,O.H=null===e||null===e.memoizedState?Vi:Wi,Eo=!1,o=n(r,a),Eo=!1,_o&&(o=Oo(t,n,r,a)),No(e),o}function No(e){O.H=Gi;var t=null!==ko&&null!==ko.next;if(vo=0,So=ko=wo=null,xo=!1,Ao=0,Lo=null,t)throw Error(i(300));null===e||Al||null!==(e=e.dependencies)&&_a(e)&&(Al=!0)}function Oo(e,t,n,r){wo=e;var a=0;do{if(_o&&(Lo=null),Ao=0,_o=!1,25<=a)throw Error(i(301));if(a+=1,So=ko=null,null!=e.updateQueue){var o=e.updateQueue;o.lastEffect=null,o.events=null,o.stores=null,null!=o.memoCache&&(o.memoCache.index=0)}O.H=Qi,o=t(n,r)}while(_o);return o}function Ro(){var e=O.H,t=e.useState()[0];return t="function"==typeof t.then?$o(t):t,e=e.useState()[0],(null!==ko?ko.memoizedState:null)!==e&&(wo.flags|=1024),t}function Do(){var e=0!==Co;return Co=0,e}function Bo(e,t,n){t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~n}function Fo(e){if(xo){for(e=e.memoizedState;null!==e;){var t=e.queue;null!==t&&(t.pending=null),e=e.next}xo=!1}vo=0,So=ko=wo=null,_o=!1,Ao=Co=0,Lo=null}function Io(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===So?wo.memoizedState=So=e:So=So.next=e,So}function zo(){if(null===ko){var e=wo.alternate;e=null!==e?e.memoizedState:null}else e=ko.next;var t=null===So?wo.memoizedState:So.next;if(null!==t)So=t,ko=e;else{if(null===e){if(null===wo.alternate)throw Error(i(467));throw Error(i(310))}e={memoizedState:(ko=e).memoizedState,baseState:ko.baseState,baseQueue:ko.baseQueue,queue:ko.queue,next:null},null===So?wo.memoizedState=So=e:So=So.next=e}return So}function $o(e){var t=Ao;return Ao+=1,null===Lo&&(Lo=[]),e=Xa(Lo,e,t),t=wo,null===(null===So?t.memoizedState:So.next)&&(t=t.alternate,O.H=null===t||null===t.memoizedState?Vi:Wi),e}function Uo(e){if(null!==e&&"object"==typeof e){if("function"==typeof e.then)return $o(e);if(e.$$typeof===k)return Ca(e)}throw Error(i(438,String(e)))}function qo(e){var t=null,n=wo.updateQueue;if(null!==n&&(t=n.memoCache),null==t){var r=wo.alternate;null!==r&&(null!==(r=r.updateQueue)&&(null!=(r=r.memoCache)&&(t={data:r.data.map(function(e){return e.slice()}),index:0})))}if(null==t&&(t={data:[],index:0}),null===n&&(n={lastEffect:null,events:null,stores:null,memoCache:null},wo.updateQueue=n),n.memoCache=t,void 0===(n=t.data[t.index]))for(n=t.data[t.index]=Array(e),r=0;r<e;r++)n[r]=L;return t.index++,n}function Ho(e,t){return"function"==typeof t?t(e):t}function Go(e){return Vo(zo(),ko,e)}function Vo(e,t,n){var r=e.queue;if(null===r)throw Error(i(311));r.lastRenderedReducer=n;var a=e.baseQueue,o=r.pending;if(null!==o){if(null!==a){var l=a.next;a.next=o.next,o.next=l}t.baseQueue=a=o,r.pending=null}if(o=e.baseState,null===a)e.memoizedState=o;else{var s=l=null,c=null,u=t=a.next,d=!1;do{var f=-536870913&u.lane;if(f!==u.lane?(oc&f)===f:(vo&f)===f){var p=u.revertLane;if(0===p)null!==c&&(c=c.next={lane:0,revertLane:0,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null}),f===Ba&&(d=!0);else{if((vo&p)===p){u=u.next,p===Ba&&(d=!0);continue}f={lane:0,revertLane:u.revertLane,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null},null===c?(s=c=f,l=o):c=c.next=f,wo.lanes|=p,pc|=p}f=u.action,Eo&&n(o,f),o=u.hasEagerState?u.eagerState:n(o,f)}else p={lane:f,revertLane:u.revertLane,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null},null===c?(s=c=p,l=o):c=c.next=p,wo.lanes|=f,pc|=f;u=u.next}while(null!==u&&u!==t);if(null===c?l=o:c.next=s,!Kn(o,e.memoizedState)&&(Al=!0,d&&null!==(n=Fa)))throw n;e.memoizedState=o,e.baseState=l,e.baseQueue=c,r.lastRenderedState=o}return null===a&&(r.lanes=0),[e.memoizedState,r.dispatch]}function Wo(e){var t=zo(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=n.dispatch,a=n.pending,o=t.memoizedState;if(null!==a){n.pending=null;var l=a=a.next;do{o=e(o,l.action),l=l.next}while(l!==a);Kn(o,t.memoizedState)||(Al=!0),t.memoizedState=o,null===t.baseQueue&&(t.baseState=o),n.lastRenderedState=o}return[o,r]}function Qo(e,t,n){var r=wo,a=zo(),o=oa;if(o){if(void 0===n)throw Error(i(407));n=n()}else n=t();var l=!Kn((ko||a).memoizedState,n);if(l&&(a.memoizedState=n,Al=!0),a=a.queue,bi(2048,8,Xo.bind(null,r,a,e),[e]),a.getSnapshot!==t||l||null!==So&&1&So.memoizedState.tag){if(r.flags|=2048,hi(9,{destroy:void 0,resource:void 0},Yo.bind(null,r,a,n,t),null),null===rc)throw Error(i(349));o||124&vo||Ko(r,t,n)}return n}function Ko(e,t,n){e.flags|=16384,e={getSnapshot:t,value:n},null===(t=wo.updateQueue)?(t={lastEffect:null,events:null,stores:null,memoCache:null},wo.updateQueue=t,t.stores=[e]):null===(n=t.stores)?t.stores=[e]:n.push(e)}function Yo(e,t,n,r){t.value=n,t.getSnapshot=r,Zo(t)&&Jo(e)}function Xo(e,t,n){return n(function(){Zo(t)&&Jo(e)})}function Zo(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!Kn(e,n)}catch(r){return!0}}function Jo(e){var t=Pr(e,2);null!==t&&Dc(t,e,2)}function ei(e){var t=Io();if("function"==typeof e){var n=e;if(e=n(),Eo){fe(!0);try{n()}finally{fe(!1)}}}return t.memoizedState=t.baseState=e,t.queue={pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ho,lastRenderedState:e},t}function ti(e,t,n,r){return e.baseState=n,Vo(e,ko,"function"==typeof r?r:Ho)}function ni(e,t,n,r,a){if(Ui(e))throw Error(i(485));if(null!==(e=t.action)){var o={payload:a,action:e,next:null,isTransition:!0,status:"pending",value:null,reason:null,listeners:[],then:function(e){o.listeners.push(e)}};null!==O.T?n(!0):o.isTransition=!1,r(o),null===(n=t.pending)?(o.next=t.pending=o,ri(t,o)):(o.next=n.next,t.pending=n.next=o)}}function ri(e,t){var n=t.action,r=t.payload,a=e.state;if(t.isTransition){var o=O.T,i={};O.T=i;try{var l=n(a,r),s=O.S;null!==s&&s(i,l),ai(e,t,l)}catch(c){ii(e,t,c)}finally{O.T=o}}else try{ai(e,t,o=n(a,r))}catch(u){ii(e,t,u)}}function ai(e,t,n){null!==n&&"object"==typeof n&&"function"==typeof n.then?n.then(function(n){oi(e,t,n)},function(n){return ii(e,t,n)}):oi(e,t,n)}function oi(e,t,n){t.status="fulfilled",t.value=n,li(t),e.state=n,null!==(t=e.pending)&&((n=t.next)===t?e.pending=null:(n=n.next,t.next=n,ri(e,n)))}function ii(e,t,n){var r=e.pending;if(e.pending=null,null!==r){r=r.next;do{t.status="rejected",t.reason=n,li(t),t=t.next}while(t!==r)}e.action=null}function li(e){e=e.listeners;for(var t=0;t<e.length;t++)(0,e[t])()}function si(e,t){return t}function ci(e,t){if(oa){var n=rc.formState;if(null!==n){e:{var r=wo;if(oa){if(aa){t:{for(var a=aa,o=la;8!==a.nodeType;){if(!o){a=null;break t}if(null===(a=bd(a.nextSibling))){a=null;break t}}a="F!"===(o=a.data)||"F"===o?a:null}if(a){aa=bd(a.nextSibling),r="F!"===a.data;break e}}ca(r)}r=!1}r&&(t=n[0])}}return(n=Io()).memoizedState=n.baseState=t,r={pending:null,lanes:0,dispatch:null,lastRenderedReducer:si,lastRenderedState:t},n.queue=r,n=Ii.bind(null,wo,r),r.dispatch=n,r=ei(!1),o=$i.bind(null,wo,!1,r.queue),a={state:t,dispatch:null,action:e,pending:null},(r=Io()).queue=a,n=ni.bind(null,wo,a,o,n),a.dispatch=n,r.memoizedState=e,[t,n,!1]}function ui(e){return di(zo(),ko,e)}function di(e,t,n){if(t=Vo(e,t,si)[0],e=Go(Ho)[0],"object"==typeof t&&null!==t&&"function"==typeof t.then)try{var r=$o(t)}catch(i){if(i===Ga)throw Wa;throw i}else r=t;var a=(t=zo()).queue,o=a.dispatch;return n!==t.memoizedState&&(wo.flags|=2048,hi(9,{destroy:void 0,resource:void 0},fi.bind(null,a,n),null)),[r,o,e]}function fi(e,t){e.action=t}function pi(e){var t=zo(),n=ko;if(null!==n)return di(t,n,e);zo(),t=t.memoizedState;var r=(n=zo()).queue.dispatch;return n.memoizedState=e,[t,r,!1]}function hi(e,t,n,r){return e={tag:e,create:n,deps:r,inst:t,next:null},null===(t=wo.updateQueue)&&(t={lastEffect:null,events:null,stores:null,memoCache:null},wo.updateQueue=t),null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function mi(){return zo().memoizedState}function gi(e,t,n,r){var a=Io();r=void 0===r?null:r,wo.flags|=e,a.memoizedState=hi(1|t,{destroy:void 0,resource:void 0},n,r)}function bi(e,t,n,r){var a=zo();r=void 0===r?null:r;var o=a.memoizedState.inst;null!==ko&&null!==r&&Po(r,ko.memoizedState.deps)?a.memoizedState=hi(t,o,n,r):(wo.flags|=e,a.memoizedState=hi(1|t,o,n,r))}function yi(e,t){gi(8390656,8,e,t)}function vi(e,t){bi(2048,8,e,t)}function wi(e,t){return bi(4,2,e,t)}function ki(e,t){return bi(4,4,e,t)}function Si(e,t){if("function"==typeof t){e=e();var n=t(e);return function(){"function"==typeof n?n():t(null)}}if(null!=t)return e=e(),t.current=e,function(){t.current=null}}function xi(e,t,n){n=null!=n?n.concat([e]):null,bi(4,4,Si.bind(null,t,e),n)}function _i(){}function Ei(e,t){var n=zo();t=void 0===t?null:t;var r=n.memoizedState;return null!==t&&Po(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function Ci(e,t){var n=zo();t=void 0===t?null:t;var r=n.memoizedState;if(null!==t&&Po(t,r[1]))return r[0];if(r=e(),Eo){fe(!0);try{e()}finally{fe(!1)}}return n.memoizedState=[r,t],r}function Ai(e,t,n){return void 0===n||1073741824&vo?e.memoizedState=t:(e.memoizedState=n,e=Rc(),wo.lanes|=e,pc|=e,n)}function Li(e,t,n,r){return Kn(n,t)?n:null!==ho.current?(e=Ai(e,n,r),Kn(e,t)||(Al=!0),e):42&vo?(e=Rc(),wo.lanes|=e,pc|=e,t):(Al=!0,e.memoizedState=n)}function Ti(e,t,n,r,a){var o=R.p;R.p=0!==o&&8>o?o:8;var i,l,s,c=O.T,u={};O.T=u,$i(e,!1,t,n);try{var d=a(),f=O.S;if(null!==f&&f(u,d),null!==d&&"object"==typeof d&&"function"==typeof d.then)zi(e,t,(i=r,l=[],s={status:"pending",value:null,reason:null,then:function(e){l.push(e)}},d.then(function(){s.status="fulfilled",s.value=i;for(var e=0;e<l.length;e++)(0,l[e])(i)},function(e){for(s.status="rejected",s.reason=e,e=0;e<l.length;e++)(0,l[e])(void 0)}),s),Oc());else zi(e,t,r,Oc())}catch(p){zi(e,t,{then:function(){},status:"rejected",reason:p},Oc())}finally{R.p=o,O.T=c}}function ji(){}function Pi(e,t,n,r){if(5!==e.tag)throw Error(i(476));var a=Mi(e).queue;Ti(e,a,t,D,null===n?ji:function(){return Ni(e),n(r)})}function Mi(e){var t=e.memoizedState;if(null!==t)return t;var n={};return(t={memoizedState:D,baseState:D,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ho,lastRenderedState:D},next:null}).next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ho,lastRenderedState:n},next:null},e.memoizedState=t,null!==(e=e.alternate)&&(e.memoizedState=t),t}function Ni(e){zi(e,Mi(e).next.queue,{},Oc())}function Oi(){return Ca(Qd)}function Ri(){return zo().memoizedState}function Di(){return zo().memoizedState}function Bi(e){for(var t=e.return;null!==t;){switch(t.tag){case 24:case 3:var n=Oc(),r=oo(t,e=ao(n),n);return null!==r&&(Dc(r,t,n),io(r,t,n)),t={cache:Na()},void(e.payload=t)}t=t.return}}function Fi(e,t,n){var r=Oc();n={lane:r,revertLane:0,action:n,hasEagerState:!1,eagerState:null,next:null},Ui(e)?qi(t,n):null!==(n=jr(e,t,n,r))&&(Dc(n,e,r),Hi(n,t,r))}function Ii(e,t,n){zi(e,t,n,Oc())}function zi(e,t,n,r){var a={lane:r,revertLane:0,action:n,hasEagerState:!1,eagerState:null,next:null};if(Ui(e))qi(t,a);else{var o=e.alternate;if(0===e.lanes&&(null===o||0===o.lanes)&&null!==(o=t.lastRenderedReducer))try{var i=t.lastRenderedState,l=o(i,n);if(a.hasEagerState=!0,a.eagerState=l,Kn(l,i))return Tr(e,t,a,0),null===rc&&Lr(),!1}catch(s){}if(null!==(n=jr(e,t,a,r)))return Dc(n,e,r),Hi(n,t,r),!0}return!1}function $i(e,t,n,r){if(r={lane:2,revertLane:Tu(),action:r,hasEagerState:!1,eagerState:null,next:null},Ui(e)){if(t)throw Error(i(479))}else null!==(t=jr(e,n,r,2))&&Dc(t,e,2)}function Ui(e){var t=e.alternate;return e===wo||null!==t&&t===wo}function qi(e,t){_o=xo=!0;var n=e.pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Hi(e,t,n){if(4194048&n){var r=t.lanes;n|=r&=e.pendingLanes,t.lanes=n,Ae(e,n)}}var Gi={readContext:Ca,use:Uo,useCallback:jo,useContext:jo,useEffect:jo,useImperativeHandle:jo,useLayoutEffect:jo,useInsertionEffect:jo,useMemo:jo,useReducer:jo,useRef:jo,useState:jo,useDebugValue:jo,useDeferredValue:jo,useTransition:jo,useSyncExternalStore:jo,useId:jo,useHostTransitionStatus:jo,useFormState:jo,useActionState:jo,useOptimistic:jo,useMemoCache:jo,useCacheRefresh:jo},Vi={readContext:Ca,use:Uo,useCallback:function(e,t){return Io().memoizedState=[e,void 0===t?null:t],e},useContext:Ca,useEffect:yi,useImperativeHandle:function(e,t,n){n=null!=n?n.concat([e]):null,gi(4194308,4,Si.bind(null,t,e),n)},useLayoutEffect:function(e,t){return gi(4194308,4,e,t)},useInsertionEffect:function(e,t){gi(4,2,e,t)},useMemo:function(e,t){var n=Io();t=void 0===t?null:t;var r=e();if(Eo){fe(!0);try{e()}finally{fe(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=Io();if(void 0!==n){var a=n(t);if(Eo){fe(!0);try{n(t)}finally{fe(!1)}}}else a=t;return r.memoizedState=r.baseState=a,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:a},r.queue=e,e=e.dispatch=Fi.bind(null,wo,e),[r.memoizedState,e]},useRef:function(e){return e={current:e},Io().memoizedState=e},useState:function(e){var t=(e=ei(e)).queue,n=Ii.bind(null,wo,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:_i,useDeferredValue:function(e,t){return Ai(Io(),e,t)},useTransition:function(){var e=ei(!1);return e=Ti.bind(null,wo,e.queue,!0,!1),Io().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=wo,a=Io();if(oa){if(void 0===n)throw Error(i(407));n=n()}else{if(n=t(),null===rc)throw Error(i(349));124&oc||Ko(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,yi(Xo.bind(null,r,o,e),[e]),r.flags|=2048,hi(9,{destroy:void 0,resource:void 0},Yo.bind(null,r,o,n,t),null),n},useId:function(){var e=Io(),t=rc.identifierPrefix;if(oa){var n=Zr;t="\xab"+t+"R"+(n=(Xr&~(1<<32-pe(Xr)-1)).toString(32)+n),0<(n=Co++)&&(t+="H"+n.toString(32)),t+="\xbb"}else t="\xab"+t+"r"+(n=To++).toString(32)+"\xbb";return e.memoizedState=t},useHostTransitionStatus:Oi,useFormState:ci,useActionState:ci,useOptimistic:function(e){var t=Io();t.memoizedState=t.baseState=e;var n={pending:null,lanes:0,dispatch:null,lastRenderedReducer:null,lastRenderedState:null};return t.queue=n,t=$i.bind(null,wo,!0,n),n.dispatch=t,[e,t]},useMemoCache:qo,useCacheRefresh:function(){return Io().memoizedState=Bi.bind(null,wo)}},Wi={readContext:Ca,use:Uo,useCallback:Ei,useContext:Ca,useEffect:vi,useImperativeHandle:xi,useInsertionEffect:wi,useLayoutEffect:ki,useMemo:Ci,useReducer:Go,useRef:mi,useState:function(){return Go(Ho)},useDebugValue:_i,useDeferredValue:function(e,t){return Li(zo(),ko.memoizedState,e,t)},useTransition:function(){var e=Go(Ho)[0],t=zo().memoizedState;return["boolean"==typeof e?e:$o(e),t]},useSyncExternalStore:Qo,useId:Ri,useHostTransitionStatus:Oi,useFormState:ui,useActionState:ui,useOptimistic:function(e,t){return ti(zo(),0,e,t)},useMemoCache:qo,useCacheRefresh:Di},Qi={readContext:Ca,use:Uo,useCallback:Ei,useContext:Ca,useEffect:vi,useImperativeHandle:xi,useInsertionEffect:wi,useLayoutEffect:ki,useMemo:Ci,useReducer:Wo,useRef:mi,useState:function(){return Wo(Ho)},useDebugValue:_i,useDeferredValue:function(e,t){var n=zo();return null===ko?Ai(n,e,t):Li(n,ko.memoizedState,e,t)},useTransition:function(){var e=Wo(Ho)[0],t=zo().memoizedState;return["boolean"==typeof e?e:$o(e),t]},useSyncExternalStore:Qo,useId:Ri,useHostTransitionStatus:Oi,useFormState:pi,useActionState:pi,useOptimistic:function(e,t){var n=zo();return null!==ko?ti(n,0,e,t):(n.baseState=e,[e,n.queue.dispatch])},useMemoCache:qo,useCacheRefresh:Di},Ki=null,Yi=0;function Xi(e){var t=Yi;return Yi+=1,null===Ki&&(Ki=[]),Xa(Ki,e,t)}function Zi(e,t){t=t.props.ref,e.ref=void 0!==t?t:null}function Ji(e,t){if(t.$$typeof===p)throw Error(i(525));throw e=Object.prototype.toString.call(t),Error(i(31,"[object Object]"===e?"object with keys {"+Object.keys(t).join(", ")+"}":e))}function el(e){return(0,e._init)(e._payload)}function tl(e){function t(t,n){if(e){var r=t.deletions;null===r?(t.deletions=[n],t.flags|=16):r.push(n)}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e){for(var t=new Map;null!==e;)null!==e.key?t.set(e.key,e):t.set(e.index,e),e=e.sibling;return t}function a(e,t){return(e=Fr(e,t)).index=0,e.sibling=null,e}function o(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.flags|=67108866,n):r:(t.flags|=67108866,n):(t.flags|=1048576,n)}function l(t){return e&&null===t.alternate&&(t.flags|=67108866),t}function s(e,t,n,r){return null===t||6!==t.tag?((t=Ur(n,e.mode,r)).return=e,t):((t=a(t,n)).return=e,t)}function c(e,t,n,r){var o=n.type;return o===g?d(e,t,n.props.children,r,n.key):null!==t&&(t.elementType===o||"object"==typeof o&&null!==o&&o.$$typeof===C&&el(o)===t.type)?(Zi(t=a(t,n.props),n),t.return=e,t):(Zi(t=zr(n.type,n.key,n.props,null,e.mode,r),n),t.return=e,t)}function u(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=qr(n,e.mode,r)).return=e,t):((t=a(t,n.children||[])).return=e,t)}function d(e,t,n,r,o){return null===t||7!==t.tag?((t=$r(n,e.mode,r,o)).return=e,t):((t=a(t,n)).return=e,t)}function f(e,t,n){if("string"==typeof t&&""!==t||"number"==typeof t||"bigint"==typeof t)return(t=Ur(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case h:return Zi(n=zr(t.type,t.key,t.props,null,e.mode,n),t),n.return=e,n;case m:return(t=qr(t,e.mode,n)).return=e,t;case C:return f(e,t=(0,t._init)(t._payload),n)}if(N(t)||j(t))return(t=$r(t,e.mode,n,null)).return=e,t;if("function"==typeof t.then)return f(e,Xi(t),n);if(t.$$typeof===k)return f(e,Aa(e,t),n);Ji(e,t)}return null}function p(e,t,n,r){var a=null!==t?t.key:null;if("string"==typeof n&&""!==n||"number"==typeof n||"bigint"==typeof n)return null!==a?null:s(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case h:return n.key===a?c(e,t,n,r):null;case m:return n.key===a?u(e,t,n,r):null;case C:return p(e,t,n=(a=n._init)(n._payload),r)}if(N(n)||j(n))return null!==a?null:d(e,t,n,r,null);if("function"==typeof n.then)return p(e,t,Xi(n),r);if(n.$$typeof===k)return p(e,t,Aa(e,n),r);Ji(e,n)}return null}function b(e,t,n,r,a){if("string"==typeof r&&""!==r||"number"==typeof r||"bigint"==typeof r)return s(t,e=e.get(n)||null,""+r,a);if("object"==typeof r&&null!==r){switch(r.$$typeof){case h:return c(t,e=e.get(null===r.key?n:r.key)||null,r,a);case m:return u(t,e=e.get(null===r.key?n:r.key)||null,r,a);case C:return b(e,t,n,r=(0,r._init)(r._payload),a)}if(N(r)||j(r))return d(t,e=e.get(n)||null,r,a,null);if("function"==typeof r.then)return b(e,t,n,Xi(r),a);if(r.$$typeof===k)return b(e,t,n,Aa(t,r),a);Ji(t,r)}return null}function y(s,c,u,d){if("object"==typeof u&&null!==u&&u.type===g&&null===u.key&&(u=u.props.children),"object"==typeof u&&null!==u){switch(u.$$typeof){case h:e:{for(var v=u.key;null!==c;){if(c.key===v){if((v=u.type)===g){if(7===c.tag){n(s,c.sibling),(d=a(c,u.props.children)).return=s,s=d;break e}}else if(c.elementType===v||"object"==typeof v&&null!==v&&v.$$typeof===C&&el(v)===c.type){n(s,c.sibling),Zi(d=a(c,u.props),u),d.return=s,s=d;break e}n(s,c);break}t(s,c),c=c.sibling}u.type===g?((d=$r(u.props.children,s.mode,d,u.key)).return=s,s=d):(Zi(d=zr(u.type,u.key,u.props,null,s.mode,d),u),d.return=s,s=d)}return l(s);case m:e:{for(v=u.key;null!==c;){if(c.key===v){if(4===c.tag&&c.stateNode.containerInfo===u.containerInfo&&c.stateNode.implementation===u.implementation){n(s,c.sibling),(d=a(c,u.children||[])).return=s,s=d;break e}n(s,c);break}t(s,c),c=c.sibling}(d=qr(u,s.mode,d)).return=s,s=d}return l(s);case C:return y(s,c,u=(v=u._init)(u._payload),d)}if(N(u))return function(a,i,l,s){for(var c=null,u=null,d=i,h=i=0,m=null;null!==d&&h<l.length;h++){d.index>h?(m=d,d=null):m=d.sibling;var g=p(a,d,l[h],s);if(null===g){null===d&&(d=m);break}e&&d&&null===g.alternate&&t(a,d),i=o(g,i,h),null===u?c=g:u.sibling=g,u=g,d=m}if(h===l.length)return n(a,d),oa&&Jr(a,h),c;if(null===d){for(;h<l.length;h++)null!==(d=f(a,l[h],s))&&(i=o(d,i,h),null===u?c=d:u.sibling=d,u=d);return oa&&Jr(a,h),c}for(d=r(d);h<l.length;h++)null!==(m=b(d,a,h,l[h],s))&&(e&&null!==m.alternate&&d.delete(null===m.key?h:m.key),i=o(m,i,h),null===u?c=m:u.sibling=m,u=m);return e&&d.forEach(function(e){return t(a,e)}),oa&&Jr(a,h),c}(s,c,u,d);if(j(u)){if("function"!=typeof(v=j(u)))throw Error(i(150));return function(a,l,s,c){if(null==s)throw Error(i(151));for(var u=null,d=null,h=l,m=l=0,g=null,y=s.next();null!==h&&!y.done;m++,y=s.next()){h.index>m?(g=h,h=null):g=h.sibling;var v=p(a,h,y.value,c);if(null===v){null===h&&(h=g);break}e&&h&&null===v.alternate&&t(a,h),l=o(v,l,m),null===d?u=v:d.sibling=v,d=v,h=g}if(y.done)return n(a,h),oa&&Jr(a,m),u;if(null===h){for(;!y.done;m++,y=s.next())null!==(y=f(a,y.value,c))&&(l=o(y,l,m),null===d?u=y:d.sibling=y,d=y);return oa&&Jr(a,m),u}for(h=r(h);!y.done;m++,y=s.next())null!==(y=b(h,a,m,y.value,c))&&(e&&null!==y.alternate&&h.delete(null===y.key?m:y.key),l=o(y,l,m),null===d?u=y:d.sibling=y,d=y);return e&&h.forEach(function(e){return t(a,e)}),oa&&Jr(a,m),u}(s,c,u=v.call(u),d)}if("function"==typeof u.then)return y(s,c,Xi(u),d);if(u.$$typeof===k)return y(s,c,Aa(s,u),d);Ji(s,u)}return"string"==typeof u&&""!==u||"number"==typeof u||"bigint"==typeof u?(u=""+u,null!==c&&6===c.tag?(n(s,c.sibling),(d=a(c,u)).return=s,s=d):(n(s,c),(d=Ur(u,s.mode,d)).return=s,s=d),l(s)):n(s,c)}return function(e,t,n,r){try{Yi=0;var a=y(e,t,n,r);return Ki=null,a}catch(i){if(i===Ga||i===Wa)throw i;var o=Dr(29,i,null,e.mode);return o.lanes=r,o.return=e,o}}}var nl=tl(!0),rl=tl(!1),al=I(null),ol=null;function il(e){var t=e.alternate;$(ul,1&ul.current),$(al,e),null===ol&&(null===t||null!==ho.current||null!==t.memoizedState)&&(ol=e)}function ll(e){if(22===e.tag){if($(ul,ul.current),$(al,e),null===ol){var t=e.alternate;null!==t&&null!==t.memoizedState&&(ol=e)}}else sl()}function sl(){$(ul,ul.current),$(al,al.current)}function cl(e){z(al),ol===e&&(ol=null),z(ul)}var ul=I(0);function dl(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||gd(n)))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(128&t.flags)return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}function fl(e,t,n,r){n=null==(n=n(r,t=e.memoizedState))?t:f({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var pl={enqueueSetState:function(e,t,n){e=e._reactInternals;var r=Oc(),a=ao(r);a.payload=t,null!=n&&(a.callback=n),null!==(t=oo(e,a,r))&&(Dc(t,e,r),io(t,e,r))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=Oc(),a=ao(r);a.tag=1,a.payload=t,null!=n&&(a.callback=n),null!==(t=oo(e,a,r))&&(Dc(t,e,r),io(t,e,r))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=Oc(),r=ao(n);r.tag=2,null!=t&&(r.callback=t),null!==(t=oo(e,r,n))&&(Dc(t,e,n),io(t,e,n))}};function hl(e,t,n,r,a,o,i){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,o,i):!t.prototype||!t.prototype.isPureReactComponent||(!Yn(n,r)||!Yn(a,o))}function ml(e,t,n,r){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&pl.enqueueReplaceState(t,t.state,null)}function gl(e,t){var n=t;if("ref"in t)for(var r in n={},t)"ref"!==r&&(n[r]=t[r]);if(e=e.defaultProps)for(var a in n===t&&(n=f({},n)),e)void 0===n[a]&&(n[a]=e[a]);return n}var bl="function"==typeof reportError?reportError:function(e){if("object"==typeof window&&"function"==typeof window.ErrorEvent){var t=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:"object"==typeof e&&null!==e&&"string"==typeof e.message?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if("object"==typeof process&&"function"==typeof process.emit)return void process.emit("uncaughtException",e);console.error(e)};function yl(e){bl(e)}function vl(e){console.error(e)}function wl(e){bl(e)}function kl(e,t){try{(0,e.onUncaughtError)(t.value,{componentStack:t.stack})}catch(n){setTimeout(function(){throw n})}}function Sl(e,t,n){try{(0,e.onCaughtError)(n.value,{componentStack:n.stack,errorBoundary:1===t.tag?t.stateNode:null})}catch(r){setTimeout(function(){throw r})}}function xl(e,t,n){return(n=ao(n)).tag=3,n.payload={element:null},n.callback=function(){kl(e,t)},n}function _l(e){return(e=ao(e)).tag=3,e}function El(e,t,n,r){var a=n.type.getDerivedStateFromError;if("function"==typeof a){var o=r.value;e.payload=function(){return a(o)},e.callback=function(){Sl(t,n,r)}}var i=n.stateNode;null!==i&&"function"==typeof i.componentDidCatch&&(e.callback=function(){Sl(t,n,r),"function"!=typeof a&&(null===_c?_c=new Set([this]):_c.add(this));var e=r.stack;this.componentDidCatch(r.value,{componentStack:null!==e?e:""})})}var Cl=Error(i(461)),Al=!1;function Ll(e,t,n,r){t.child=null===e?rl(t,null,n,r):nl(t,e.child,n,r)}function Tl(e,t,n,r,a){n=n.render;var o=t.ref;if("ref"in r){var i={};for(var l in r)"ref"!==l&&(i[l]=r[l])}else i=r;return Ea(t),r=Mo(e,t,n,i,o,a),l=Do(),null===e||Al?(oa&&l&&ta(t),t.flags|=1,Ll(e,t,r,a),t.child):(Bo(e,t,a),Kl(e,t,a))}function jl(e,t,n,r,a){if(null===e){var o=n.type;return"function"!=typeof o||Br(o)||void 0!==o.defaultProps||null!==n.compare?((e=zr(n.type,null,r,t,t.mode,a)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=o,Pl(e,t,o,r,a))}if(o=e.child,!Yl(e,a)){var i=o.memoizedProps;if((n=null!==(n=n.compare)?n:Yn)(i,r)&&e.ref===t.ref)return Kl(e,t,a)}return t.flags|=1,(e=Fr(o,r)).ref=t.ref,e.return=t,t.child=e}function Pl(e,t,n,r,a){if(null!==e){var o=e.memoizedProps;if(Yn(o,r)&&e.ref===t.ref){if(Al=!1,t.pendingProps=r=o,!Yl(e,a))return t.lanes=e.lanes,Kl(e,t,a);131072&e.flags&&(Al=!0)}}return Rl(e,t,n,r,a)}function Ml(e,t,n){var r=t.pendingProps,a=r.children,o=null!==e?e.memoizedState:null;if("hidden"===r.mode){if(128&t.flags){if(r=null!==o?o.baseLanes|n:n,null!==e){for(a=t.child=e.child,o=0;null!==a;)o=o|a.lanes|a.childLanes,a=a.sibling;t.childLanes=o&~r}else t.childLanes=0,t.child=null;return Nl(e,t,r,n)}if(!(536870912&n))return t.lanes=t.childLanes=536870912,Nl(e,t,null!==o?o.baseLanes|n:n,n);t.memoizedState={baseLanes:0,cachePool:null},null!==e&&qa(0,null!==o?o.cachePool:null),null!==o?go(t,o):bo(),ll(t)}else null!==o?(qa(0,o.cachePool),go(t,o),sl(),t.memoizedState=null):(null!==e&&qa(0,null),bo(),sl());return Ll(e,t,a,n),t.child}function Nl(e,t,n,r){var a=Ua();return a=null===a?null:{parent:Ma._currentValue,pool:a},t.memoizedState={baseLanes:n,cachePool:a},null!==e&&qa(0,null),bo(),ll(t),null!==e&&xa(e,t,r,!0),null}function Ol(e,t){var n=t.ref;if(null===n)null!==e&&null!==e.ref&&(t.flags|=4194816);else{if("function"!=typeof n&&"object"!=typeof n)throw Error(i(284));null!==e&&e.ref===n||(t.flags|=4194816)}}function Rl(e,t,n,r,a){return Ea(t),n=Mo(e,t,n,r,void 0,a),r=Do(),null===e||Al?(oa&&r&&ta(t),t.flags|=1,Ll(e,t,n,a),t.child):(Bo(e,t,a),Kl(e,t,a))}function Dl(e,t,n,r,a,o){return Ea(t),t.updateQueue=null,n=Oo(t,r,n,a),No(e),r=Do(),null===e||Al?(oa&&r&&ta(t),t.flags|=1,Ll(e,t,n,o),t.child):(Bo(e,t,o),Kl(e,t,o))}function Bl(e,t,n,r,a){if(Ea(t),null===t.stateNode){var o=Or,i=n.contextType;"object"==typeof i&&null!==i&&(o=Ca(i)),o=new n(r,o),t.memoizedState=null!==o.state&&void 0!==o.state?o.state:null,o.updater=pl,t.stateNode=o,o._reactInternals=t,(o=t.stateNode).props=r,o.state=t.memoizedState,o.refs={},no(t),i=n.contextType,o.context="object"==typeof i&&null!==i?Ca(i):Or,o.state=t.memoizedState,"function"==typeof(i=n.getDerivedStateFromProps)&&(fl(t,n,i,r),o.state=t.memoizedState),"function"==typeof n.getDerivedStateFromProps||"function"==typeof o.getSnapshotBeforeUpdate||"function"!=typeof o.UNSAFE_componentWillMount&&"function"!=typeof o.componentWillMount||(i=o.state,"function"==typeof o.componentWillMount&&o.componentWillMount(),"function"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount(),i!==o.state&&pl.enqueueReplaceState(o,o.state,null),uo(t,r,o,a),co(),o.state=t.memoizedState),"function"==typeof o.componentDidMount&&(t.flags|=4194308),r=!0}else if(null===e){o=t.stateNode;var l=t.memoizedProps,s=gl(n,l);o.props=s;var c=o.context,u=n.contextType;i=Or,"object"==typeof u&&null!==u&&(i=Ca(u));var d=n.getDerivedStateFromProps;u="function"==typeof d||"function"==typeof o.getSnapshotBeforeUpdate,l=t.pendingProps!==l,u||"function"!=typeof o.UNSAFE_componentWillReceiveProps&&"function"!=typeof o.componentWillReceiveProps||(l||c!==i)&&ml(t,o,r,i),to=!1;var f=t.memoizedState;o.state=f,uo(t,r,o,a),co(),c=t.memoizedState,l||f!==c||to?("function"==typeof d&&(fl(t,n,d,r),c=t.memoizedState),(s=to||hl(t,n,s,r,f,c,i))?(u||"function"!=typeof o.UNSAFE_componentWillMount&&"function"!=typeof o.componentWillMount||("function"==typeof o.componentWillMount&&o.componentWillMount(),"function"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount()),"function"==typeof o.componentDidMount&&(t.flags|=4194308)):("function"==typeof o.componentDidMount&&(t.flags|=4194308),t.memoizedProps=r,t.memoizedState=c),o.props=r,o.state=c,o.context=i,r=s):("function"==typeof o.componentDidMount&&(t.flags|=4194308),r=!1)}else{o=t.stateNode,ro(e,t),u=gl(n,i=t.memoizedProps),o.props=u,d=t.pendingProps,f=o.context,c=n.contextType,s=Or,"object"==typeof c&&null!==c&&(s=Ca(c)),(c="function"==typeof(l=n.getDerivedStateFromProps)||"function"==typeof o.getSnapshotBeforeUpdate)||"function"!=typeof o.UNSAFE_componentWillReceiveProps&&"function"!=typeof o.componentWillReceiveProps||(i!==d||f!==s)&&ml(t,o,r,s),to=!1,f=t.memoizedState,o.state=f,uo(t,r,o,a),co();var p=t.memoizedState;i!==d||f!==p||to||null!==e&&null!==e.dependencies&&_a(e.dependencies)?("function"==typeof l&&(fl(t,n,l,r),p=t.memoizedState),(u=to||hl(t,n,u,r,f,p,s)||null!==e&&null!==e.dependencies&&_a(e.dependencies))?(c||"function"!=typeof o.UNSAFE_componentWillUpdate&&"function"!=typeof o.componentWillUpdate||("function"==typeof o.componentWillUpdate&&o.componentWillUpdate(r,p,s),"function"==typeof o.UNSAFE_componentWillUpdate&&o.UNSAFE_componentWillUpdate(r,p,s)),"function"==typeof o.componentDidUpdate&&(t.flags|=4),"function"==typeof o.getSnapshotBeforeUpdate&&(t.flags|=1024)):("function"!=typeof o.componentDidUpdate||i===e.memoizedProps&&f===e.memoizedState||(t.flags|=4),"function"!=typeof o.getSnapshotBeforeUpdate||i===e.memoizedProps&&f===e.memoizedState||(t.flags|=1024),t.memoizedProps=r,t.memoizedState=p),o.props=r,o.state=p,o.context=s,r=u):("function"!=typeof o.componentDidUpdate||i===e.memoizedProps&&f===e.memoizedState||(t.flags|=4),"function"!=typeof o.getSnapshotBeforeUpdate||i===e.memoizedProps&&f===e.memoizedState||(t.flags|=1024),r=!1)}return o=r,Ol(e,t),r=!!(128&t.flags),o||r?(o=t.stateNode,n=r&&"function"!=typeof n.getDerivedStateFromError?null:o.render(),t.flags|=1,null!==e&&r?(t.child=nl(t,e.child,null,a),t.child=nl(t,null,n,a)):Ll(e,t,n,a),t.memoizedState=o.state,e=t.child):e=Kl(e,t,a),e}function Fl(e,t,n,r){return pa(),t.flags|=256,Ll(e,t,n,r),t.child}var Il={dehydrated:null,treeContext:null,retryLane:0,hydrationErrors:null};function zl(e){return{baseLanes:e,cachePool:Ha()}}function $l(e,t,n){return e=null!==e?e.childLanes&~n:0,t&&(e|=gc),e}function Ul(e,t,n){var r,a=t.pendingProps,o=!1,l=!!(128&t.flags);if((r=l)||(r=(null===e||null!==e.memoizedState)&&!!(2&ul.current)),r&&(o=!0,t.flags&=-129),r=!!(32&t.flags),t.flags&=-33,null===e){if(oa){if(o?il(t):sl(),oa){var s,c=aa;if(s=c){e:{for(s=c,c=la;8!==s.nodeType;){if(!c){c=null;break e}if(null===(s=bd(s.nextSibling))){c=null;break e}}c=s}null!==c?(t.memoizedState={dehydrated:c,treeContext:null!==Yr?{id:Xr,overflow:Zr}:null,retryLane:536870912,hydrationErrors:null},(s=Dr(18,null,null,0)).stateNode=c,s.return=t,t.child=s,ra=t,aa=null,s=!0):s=!1}s||ca(t)}if(null!==(c=t.memoizedState)&&null!==(c=c.dehydrated))return gd(c)?t.lanes=32:t.lanes=536870912,null;cl(t)}return c=a.children,a=a.fallback,o?(sl(),c=Hl({mode:"hidden",children:c},o=t.mode),a=$r(a,o,n,null),c.return=t,a.return=t,c.sibling=a,t.child=c,(o=t.child).memoizedState=zl(n),o.childLanes=$l(e,r,n),t.memoizedState=Il,a):(il(t),ql(t,c))}if(null!==(s=e.memoizedState)&&null!==(c=s.dehydrated)){if(l)256&t.flags?(il(t),t.flags&=-257,t=Gl(e,t,n)):null!==t.memoizedState?(sl(),t.child=e.child,t.flags|=128,t=null):(sl(),o=a.fallback,c=t.mode,a=Hl({mode:"visible",children:a.children},c),(o=$r(o,c,n,null)).flags|=2,a.return=t,o.return=t,a.sibling=o,t.child=a,nl(t,e.child,null,n),(a=t.child).memoizedState=zl(n),a.childLanes=$l(e,r,n),t.memoizedState=Il,t=o);else if(il(t),gd(c)){if(r=c.nextSibling&&c.nextSibling.dataset)var u=r.dgst;r=u,(a=Error(i(419))).stack="",a.digest=r,ma({value:a,source:null,stack:null}),t=Gl(e,t,n)}else if(Al||xa(e,t,n,!1),r=0!==(n&e.childLanes),Al||r){if(null!==(r=rc)&&(0!==(a=0!==((a=42&(a=n&-n)?1:Le(a))&(r.suspendedLanes|n))?0:a)&&a!==s.retryLane))throw s.retryLane=a,Pr(e,a),Dc(r,e,a),Cl;"$?"===c.data||Wc(),t=Gl(e,t,n)}else"$?"===c.data?(t.flags|=192,t.child=e.child,t=null):(e=s.treeContext,aa=bd(c.nextSibling),ra=t,oa=!0,ia=null,la=!1,null!==e&&(Qr[Kr++]=Xr,Qr[Kr++]=Zr,Qr[Kr++]=Yr,Xr=e.id,Zr=e.overflow,Yr=t),(t=ql(t,a.children)).flags|=4096);return t}return o?(sl(),o=a.fallback,c=t.mode,u=(s=e.child).sibling,(a=Fr(s,{mode:"hidden",children:a.children})).subtreeFlags=65011712&s.subtreeFlags,null!==u?o=Fr(u,o):(o=$r(o,c,n,null)).flags|=2,o.return=t,a.return=t,a.sibling=o,t.child=a,a=o,o=t.child,null===(c=e.child.memoizedState)?c=zl(n):(null!==(s=c.cachePool)?(u=Ma._currentValue,s=s.parent!==u?{parent:u,pool:u}:s):s=Ha(),c={baseLanes:c.baseLanes|n,cachePool:s}),o.memoizedState=c,o.childLanes=$l(e,r,n),t.memoizedState=Il,a):(il(t),e=(n=e.child).sibling,(n=Fr(n,{mode:"visible",children:a.children})).return=t,n.sibling=null,null!==e&&(null===(r=t.deletions)?(t.deletions=[e],t.flags|=16):r.push(e)),t.child=n,t.memoizedState=null,n)}function ql(e,t){return(t=Hl({mode:"visible",children:t},e.mode)).return=e,e.child=t}function Hl(e,t){return(e=Dr(22,e,null,t)).lanes=0,e.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null},e}function Gl(e,t,n){return nl(t,e.child,null,n),(e=ql(t,t.pendingProps.children)).flags|=2,t.memoizedState=null,e}function Vl(e,t,n){e.lanes|=t;var r=e.alternate;null!==r&&(r.lanes|=t),ka(e.return,t,n)}function Wl(e,t,n,r,a){var o=e.memoizedState;null===o?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:a}:(o.isBackwards=t,o.rendering=null,o.renderingStartTime=0,o.last=r,o.tail=n,o.tailMode=a)}function Ql(e,t,n){var r=t.pendingProps,a=r.revealOrder,o=r.tail;if(Ll(e,t,r.children,n),2&(r=ul.current))r=1&r|2,t.flags|=128;else{if(null!==e&&128&e.flags)e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&Vl(e,n,t);else if(19===e.tag)Vl(e,n,t);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}switch($(ul,r),a){case"forwards":for(n=t.child,a=null;null!==n;)null!==(e=n.alternate)&&null===dl(e)&&(a=n),n=n.sibling;null===(n=a)?(a=t.child,t.child=null):(a=n.sibling,n.sibling=null),Wl(t,!1,a,n,o);break;case"backwards":for(n=null,a=t.child,t.child=null;null!==a;){if(null!==(e=a.alternate)&&null===dl(e)){t.child=a;break}e=a.sibling,a.sibling=n,n=a,a=e}Wl(t,!0,n,null,o);break;case"together":Wl(t,!1,null,null,void 0);break;default:t.memoizedState=null}return t.child}function Kl(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),pc|=t.lanes,0===(n&t.childLanes)){if(null===e)return null;if(xa(e,t,n,!1),0===(n&t.childLanes))return null}if(null!==e&&t.child!==e.child)throw Error(i(153));if(null!==t.child){for(n=Fr(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Fr(e,e.pendingProps)).return=t;n.sibling=null}return t.child}function Yl(e,t){return 0!==(e.lanes&t)||!(null===(e=e.dependencies)||!_a(e))}function Xl(e,t,n){if(null!==e)if(e.memoizedProps!==t.pendingProps)Al=!0;else{if(!(Yl(e,n)||128&t.flags))return Al=!1,function(e,t,n){switch(t.tag){case 3:V(t,t.stateNode.containerInfo),va(0,Ma,e.memoizedState.cache),pa();break;case 27:case 5:Q(t);break;case 4:V(t,t.stateNode.containerInfo);break;case 10:va(0,t.type,t.memoizedProps.value);break;case 13:var r=t.memoizedState;if(null!==r)return null!==r.dehydrated?(il(t),t.flags|=128,null):0!==(n&t.child.childLanes)?Ul(e,t,n):(il(t),null!==(e=Kl(e,t,n))?e.sibling:null);il(t);break;case 19:var a=!!(128&e.flags);if((r=0!==(n&t.childLanes))||(xa(e,t,n,!1),r=0!==(n&t.childLanes)),a){if(r)return Ql(e,t,n);t.flags|=128}if(null!==(a=t.memoizedState)&&(a.rendering=null,a.tail=null,a.lastEffect=null),$(ul,ul.current),r)break;return null;case 22:case 23:return t.lanes=0,Ml(e,t,n);case 24:va(0,Ma,e.memoizedState.cache)}return Kl(e,t,n)}(e,t,n);Al=!!(131072&e.flags)}else Al=!1,oa&&1048576&t.flags&&ea(t,Wr,t.index);switch(t.lanes=0,t.tag){case 16:e:{e=t.pendingProps;var r=t.elementType,a=r._init;if(r=a(r._payload),t.type=r,"function"!=typeof r){if(null!=r){if((a=r.$$typeof)===S){t.tag=11,t=Tl(null,t,r,e,n);break e}if(a===E){t.tag=14,t=jl(null,t,r,e,n);break e}}throw t=M(r)||r,Error(i(306,t,""))}Br(r)?(e=gl(r,e),t.tag=1,t=Bl(null,t,r,e,n)):(t.tag=0,t=Rl(null,t,r,e,n))}return t;case 0:return Rl(e,t,t.type,t.pendingProps,n);case 1:return Bl(e,t,r=t.type,a=gl(r,t.pendingProps),n);case 3:e:{if(V(t,t.stateNode.containerInfo),null===e)throw Error(i(387));r=t.pendingProps;var o=t.memoizedState;a=o.element,ro(e,t),uo(t,r,null,n);var l=t.memoizedState;if(r=l.cache,va(0,Ma,r),r!==o.cache&&Sa(t,[Ma],n,!0),co(),r=l.element,o.isDehydrated){if(o={element:r,isDehydrated:!1,cache:l.cache},t.updateQueue.baseState=o,t.memoizedState=o,256&t.flags){t=Fl(e,t,r,n);break e}if(r!==a){ma(a=_r(Error(i(424)),t)),t=Fl(e,t,r,n);break e}if(9===(e=t.stateNode.containerInfo).nodeType)e=e.body;else e="HTML"===e.nodeName?e.ownerDocument.body:e;for(aa=bd(e.firstChild),ra=t,oa=!0,ia=null,la=!0,n=rl(t,null,r,n),t.child=n;n;)n.flags=-3&n.flags|4096,n=n.sibling}else{if(pa(),r===a){t=Kl(e,t,n);break e}Ll(e,t,r,n)}t=t.child}return t;case 26:return Ol(e,t),null===e?(n=Ld(t.type,null,t.pendingProps,null))?t.memoizedState=n:oa||(n=t.type,e=t.pendingProps,(r=rd(H.current).createElement(n))[Me]=t,r[Ne]=e,ed(r,n,e),Ge(r),t.stateNode=r):t.memoizedState=Ld(t.type,e.memoizedProps,t.pendingProps,e.memoizedState),null;case 27:return Q(t),null===e&&oa&&(r=t.stateNode=wd(t.type,t.pendingProps,H.current),ra=t,la=!0,a=aa,pd(t.type)?(yd=a,aa=bd(r.firstChild)):aa=a),Ll(e,t,t.pendingProps.children,n),Ol(e,t),null===e&&(t.flags|=4194304),t.child;case 5:return null===e&&oa&&((a=r=aa)&&(null!==(r=function(e,t,n,r){for(;1===e.nodeType;){var a=n;if(e.nodeName.toLowerCase()!==t.toLowerCase()){if(!r&&("INPUT"!==e.nodeName||"hidden"!==e.type))break}else if(r){if(!e[Ie])switch(t){case"meta":if(!e.hasAttribute("itemprop"))break;return e;case"link":if("stylesheet"===(o=e.getAttribute("rel"))&&e.hasAttribute("data-precedence"))break;if(o!==a.rel||e.getAttribute("href")!==(null==a.href||""===a.href?null:a.href)||e.getAttribute("crossorigin")!==(null==a.crossOrigin?null:a.crossOrigin)||e.getAttribute("title")!==(null==a.title?null:a.title))break;return e;case"style":if(e.hasAttribute("data-precedence"))break;return e;case"script":if(((o=e.getAttribute("src"))!==(null==a.src?null:a.src)||e.getAttribute("type")!==(null==a.type?null:a.type)||e.getAttribute("crossorigin")!==(null==a.crossOrigin?null:a.crossOrigin))&&o&&e.hasAttribute("async")&&!e.hasAttribute("itemprop"))break;return e;default:return e}}else{if("input"!==t||"hidden"!==e.type)return e;var o=null==a.name?null:""+a.name;if("hidden"===a.type&&e.getAttribute("name")===o)return e}if(null===(e=bd(e.nextSibling)))break}return null}(r,t.type,t.pendingProps,la))?(t.stateNode=r,ra=t,aa=bd(r.firstChild),la=!1,a=!0):a=!1),a||ca(t)),Q(t),a=t.type,o=t.pendingProps,l=null!==e?e.memoizedProps:null,r=o.children,id(a,o)?r=null:null!==l&&id(a,l)&&(t.flags|=32),null!==t.memoizedState&&(a=Mo(e,t,Ro,null,null,n),Qd._currentValue=a),Ol(e,t),Ll(e,t,r,n),t.child;case 6:return null===e&&oa&&((e=n=aa)&&(null!==(n=function(e,t,n){if(""===t)return null;for(;3!==e.nodeType;){if((1!==e.nodeType||"INPUT"!==e.nodeName||"hidden"!==e.type)&&!n)return null;if(null===(e=bd(e.nextSibling)))return null}return e}(n,t.pendingProps,la))?(t.stateNode=n,ra=t,aa=null,e=!0):e=!1),e||ca(t)),null;case 13:return Ul(e,t,n);case 4:return V(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=nl(t,null,r,n):Ll(e,t,r,n),t.child;case 11:return Tl(e,t,t.type,t.pendingProps,n);case 7:return Ll(e,t,t.pendingProps,n),t.child;case 8:case 12:return Ll(e,t,t.pendingProps.children,n),t.child;case 10:return r=t.pendingProps,va(0,t.type,r.value),Ll(e,t,r.children,n),t.child;case 9:return a=t.type._context,r=t.pendingProps.children,Ea(t),r=r(a=Ca(a)),t.flags|=1,Ll(e,t,r,n),t.child;case 14:return jl(e,t,t.type,t.pendingProps,n);case 15:return Pl(e,t,t.type,t.pendingProps,n);case 19:return Ql(e,t,n);case 31:return r=t.pendingProps,n=t.mode,r={mode:r.mode,children:r.children},null===e?((n=Hl(r,n)).ref=t.ref,t.child=n,n.return=t,t=n):((n=Fr(e.child,r)).ref=t.ref,t.child=n,n.return=t,t=n),t;case 22:return Ml(e,t,n);case 24:return Ea(t),r=Ca(Ma),null===e?(null===(a=Ua())&&(a=rc,o=Na(),a.pooledCache=o,o.refCount++,null!==o&&(a.pooledCacheLanes|=n),a=o),t.memoizedState={parent:r,cache:a},no(t),va(0,Ma,a)):(0!==(e.lanes&n)&&(ro(e,t),uo(t,null,null,n),co()),a=e.memoizedState,o=t.memoizedState,a.parent!==r?(a={parent:r,cache:r},t.memoizedState=a,0===t.lanes&&(t.memoizedState=t.updateQueue.baseState=a),va(0,Ma,r)):(r=o.cache,va(0,Ma,r),r!==a.cache&&Sa(t,[Ma],n,!0))),Ll(e,t,t.pendingProps.children,n),t.child;case 29:throw t.pendingProps}throw Error(i(156,t.tag))}function Zl(e){e.flags|=4}function Jl(e,t){if("stylesheet"!==t.type||4&t.state.loading)e.flags&=-16777217;else if(e.flags|=16777216,!$d(t)){if(null!==(t=al.current)&&((4194048&oc)===oc?null!==ol:(62914560&oc)!==oc&&!(536870912&oc)||t!==ol))throw Za=Qa,Va;e.flags|=8192}}function es(e,t){null!==t&&(e.flags|=4),16384&e.flags&&(t=22!==e.tag?xe():536870912,e.lanes|=t,bc|=t)}function ts(e,t){if(!oa)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?t||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function ns(e){var t=null!==e.alternate&&e.alternate.child===e.child,n=0,r=0;if(t)for(var a=e.child;null!==a;)n|=a.lanes|a.childLanes,r|=65011712&a.subtreeFlags,r|=65011712&a.flags,a.return=e,a=a.sibling;else for(a=e.child;null!==a;)n|=a.lanes|a.childLanes,r|=a.subtreeFlags,r|=a.flags,a.return=e,a=a.sibling;return e.subtreeFlags|=r,e.childLanes=n,t}function rs(e,t,n){var r=t.pendingProps;switch(na(t),t.tag){case 31:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:case 1:return ns(t),null;case 3:return n=t.stateNode,r=null,null!==e&&(r=e.memoizedState.cache),t.memoizedState.cache!==r&&(t.flags|=2048),wa(Ma),W(),n.pendingContext&&(n.context=n.pendingContext,n.pendingContext=null),null!==e&&null!==e.child||(fa(t)?Zl(t):null===e||e.memoizedState.isDehydrated&&!(256&t.flags)||(t.flags|=1024,ha())),ns(t),null;case 26:return n=t.memoizedState,null===e?(Zl(t),null!==n?(ns(t),Jl(t,n)):(ns(t),t.flags&=-16777217)):n?n!==e.memoizedState?(Zl(t),ns(t),Jl(t,n)):(ns(t),t.flags&=-16777217):(e.memoizedProps!==r&&Zl(t),ns(t),t.flags&=-16777217),null;case 27:K(t),n=H.current;var a=t.type;if(null!==e&&null!=t.stateNode)e.memoizedProps!==r&&Zl(t);else{if(!r){if(null===t.stateNode)throw Error(i(166));return ns(t),null}e=U.current,fa(t)?ua(t):(e=wd(a,r,n),t.stateNode=e,Zl(t))}return ns(t),null;case 5:if(K(t),n=t.type,null!==e&&null!=t.stateNode)e.memoizedProps!==r&&Zl(t);else{if(!r){if(null===t.stateNode)throw Error(i(166));return ns(t),null}if(e=U.current,fa(t))ua(t);else{switch(a=rd(H.current),e){case 1:e=a.createElementNS("http://www.w3.org/2000/svg",n);break;case 2:e=a.createElementNS("http://www.w3.org/1998/Math/MathML",n);break;default:switch(n){case"svg":e=a.createElementNS("http://www.w3.org/2000/svg",n);break;case"math":e=a.createElementNS("http://www.w3.org/1998/Math/MathML",n);break;case"script":(e=a.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild);break;case"select":e="string"==typeof r.is?a.createElement("select",{is:r.is}):a.createElement("select"),r.multiple?e.multiple=!0:r.size&&(e.size=r.size);break;default:e="string"==typeof r.is?a.createElement(n,{is:r.is}):a.createElement(n)}}e[Me]=t,e[Ne]=r;e:for(a=t.child;null!==a;){if(5===a.tag||6===a.tag)e.appendChild(a.stateNode);else if(4!==a.tag&&27!==a.tag&&null!==a.child){a.child.return=a,a=a.child;continue}if(a===t)break e;for(;null===a.sibling;){if(null===a.return||a.return===t)break e;a=a.return}a.sibling.return=a.return,a=a.sibling}t.stateNode=e;e:switch(ed(e,n,r),n){case"button":case"input":case"select":case"textarea":e=!!r.autoFocus;break e;case"img":e=!0;break e;default:e=!1}e&&Zl(t)}}return ns(t),t.flags&=-16777217,null;case 6:if(e&&null!=t.stateNode)e.memoizedProps!==r&&Zl(t);else{if("string"!=typeof r&&null===t.stateNode)throw Error(i(166));if(e=H.current,fa(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,null!==(a=ra))switch(a.tag){case 27:case 5:r=a.memoizedProps}e[Me]=t,(e=!!(e.nodeValue===n||null!==r&&!0===r.suppressHydrationWarning||Yu(e.nodeValue,n)))||ca(t)}else(e=rd(e).createTextNode(r))[Me]=t,t.stateNode=e}return ns(t),null;case 13:if(r=t.memoizedState,null===e||null!==e.memoizedState&&null!==e.memoizedState.dehydrated){if(a=fa(t),null!==r&&null!==r.dehydrated){if(null===e){if(!a)throw Error(i(318));if(!(a=null!==(a=t.memoizedState)?a.dehydrated:null))throw Error(i(317));a[Me]=t}else pa(),!(128&t.flags)&&(t.memoizedState=null),t.flags|=4;ns(t),a=!1}else a=ha(),null!==e&&null!==e.memoizedState&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return 256&t.flags?(cl(t),t):(cl(t),null)}if(cl(t),128&t.flags)return t.lanes=n,t;if(n=null!==r,e=null!==e&&null!==e.memoizedState,n){a=null,null!==(r=t.child).alternate&&null!==r.alternate.memoizedState&&null!==r.alternate.memoizedState.cachePool&&(a=r.alternate.memoizedState.cachePool.pool);var o=null;null!==r.memoizedState&&null!==r.memoizedState.cachePool&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)}return n!==e&&n&&(t.child.flags|=8192),es(t,t.updateQueue),ns(t),null;case 4:return W(),null===e&&zu(t.stateNode.containerInfo),ns(t),null;case 10:return wa(t.type),ns(t),null;case 19:if(z(ul),null===(a=t.memoizedState))return ns(t),null;if(r=!!(128&t.flags),null===(o=a.rendering))if(r)ts(a,!1);else{if(0!==fc||null!==e&&128&e.flags)for(e=t.child;null!==e;){if(null!==(o=dl(e))){for(t.flags|=128,ts(a,!1),e=o.updateQueue,t.updateQueue=e,es(t,e),t.subtreeFlags=0,e=n,n=t.child;null!==n;)Ir(n,e),n=n.sibling;return $(ul,1&ul.current|2),t.child}e=e.sibling}null!==a.tail&&te()>Sc&&(t.flags|=128,r=!0,ts(a,!1),t.lanes=4194304)}else{if(!r)if(null!==(e=dl(o))){if(t.flags|=128,r=!0,e=e.updateQueue,t.updateQueue=e,es(t,e),ts(a,!0),null===a.tail&&"hidden"===a.tailMode&&!o.alternate&&!oa)return ns(t),null}else 2*te()-a.renderingStartTime>Sc&&536870912!==n&&(t.flags|=128,r=!0,ts(a,!1),t.lanes=4194304);a.isBackwards?(o.sibling=t.child,t.child=o):(null!==(e=a.last)?e.sibling=o:t.child=o,a.last=o)}return null!==a.tail?(t=a.tail,a.rendering=t,a.tail=t.sibling,a.renderingStartTime=te(),t.sibling=null,e=ul.current,$(ul,r?1&e|2:1&e),t):(ns(t),null);case 22:case 23:return cl(t),yo(),r=null!==t.memoizedState,null!==e?null!==e.memoizedState!==r&&(t.flags|=8192):r&&(t.flags|=8192),r?!!(536870912&n)&&!(128&t.flags)&&(ns(t),6&t.subtreeFlags&&(t.flags|=8192)):ns(t),null!==(n=t.updateQueue)&&es(t,n.retryQueue),n=null,null!==e&&null!==e.memoizedState&&null!==e.memoizedState.cachePool&&(n=e.memoizedState.cachePool.pool),r=null,null!==t.memoizedState&&null!==t.memoizedState.cachePool&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),null!==e&&z($a),null;case 24:return n=null,null!==e&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),wa(Ma),ns(t),null;case 25:case 30:return null}throw Error(i(156,t.tag))}function as(e,t){switch(na(t),t.tag){case 1:return 65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 3:return wa(Ma),W(),65536&(e=t.flags)&&!(128&e)?(t.flags=-65537&e|128,t):null;case 26:case 27:case 5:return K(t),null;case 13:if(cl(t),null!==(e=t.memoizedState)&&null!==e.dehydrated){if(null===t.alternate)throw Error(i(340));pa()}return 65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 19:return z(ul),null;case 4:return W(),null;case 10:return wa(t.type),null;case 22:case 23:return cl(t),yo(),null!==e&&z($a),65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 24:return wa(Ma),null;default:return null}}function os(e,t){switch(na(t),t.tag){case 3:wa(Ma),W();break;case 26:case 27:case 5:K(t);break;case 4:W();break;case 13:cl(t);break;case 19:z(ul);break;case 10:wa(t.type);break;case 22:case 23:cl(t),yo(),null!==e&&z($a);break;case 24:wa(Ma)}}function is(e,t){try{var n=t.updateQueue,r=null!==n?n.lastEffect:null;if(null!==r){var a=r.next;n=a;do{if((n.tag&e)===e){r=void 0;var o=n.create,i=n.inst;r=o(),i.destroy=r}n=n.next}while(n!==a)}}catch(l){uu(t,t.return,l)}}function ls(e,t,n){try{var r=t.updateQueue,a=null!==r?r.lastEffect:null;if(null!==a){var o=a.next;r=o;do{if((r.tag&e)===e){var i=r.inst,l=i.destroy;if(void 0!==l){i.destroy=void 0,a=t;var s=n,c=l;try{c()}catch(u){uu(a,s,u)}}}r=r.next}while(r!==o)}}catch(u){uu(t,t.return,u)}}function ss(e){var t=e.updateQueue;if(null!==t){var n=e.stateNode;try{po(t,n)}catch(r){uu(e,e.return,r)}}}function cs(e,t,n){n.props=gl(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(r){uu(e,t,r)}}function us(e,t){try{var n=e.ref;if(null!==n){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;default:r=e.stateNode}"function"==typeof n?e.refCleanup=n(r):n.current=r}}catch(a){uu(e,t,a)}}function ds(e,t){var n=e.ref,r=e.refCleanup;if(null!==n)if("function"==typeof r)try{r()}catch(a){uu(e,t,a)}finally{e.refCleanup=null,null!=(e=e.alternate)&&(e.refCleanup=null)}else if("function"==typeof n)try{n(null)}catch(o){uu(e,t,o)}else n.current=null}function fs(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{e:switch(t){case"button":case"input":case"select":case"textarea":n.autoFocus&&r.focus();break e;case"img":n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(a){uu(e,e.return,a)}}function ps(e,t,n){try{var r=e.stateNode;!function(e,t,n,r){switch(t){case"div":case"span":case"svg":case"path":case"a":case"g":case"p":case"li":break;case"input":var a=null,o=null,l=null,s=null,c=null,u=null,d=null;for(h in n){var f=n[h];if(n.hasOwnProperty(h)&&null!=f)switch(h){case"checked":case"value":break;case"defaultValue":c=f;default:r.hasOwnProperty(h)||Zu(e,t,h,null,r,f)}}for(var p in r){var h=r[p];if(f=n[p],r.hasOwnProperty(p)&&(null!=h||null!=f))switch(p){case"type":o=h;break;case"name":a=h;break;case"checked":u=h;break;case"defaultChecked":d=h;break;case"value":l=h;break;case"defaultValue":s=h;break;case"children":case"dangerouslySetInnerHTML":if(null!=h)throw Error(i(137,t));break;default:h!==f&&Zu(e,t,p,h,r,f)}}return void gt(e,l,s,c,u,d,o,a);case"select":for(o in h=l=s=p=null,n)if(c=n[o],n.hasOwnProperty(o)&&null!=c)switch(o){case"value":break;case"multiple":h=c;default:r.hasOwnProperty(o)||Zu(e,t,o,null,r,c)}for(a in r)if(o=r[a],c=n[a],r.hasOwnProperty(a)&&(null!=o||null!=c))switch(a){case"value":p=o;break;case"defaultValue":s=o;break;case"multiple":l=o;default:o!==c&&Zu(e,t,a,o,r,c)}return t=s,n=l,r=h,void(null!=p?vt(e,!!n,p,!1):!!r!=!!n&&(null!=t?vt(e,!!n,t,!0):vt(e,!!n,n?[]:"",!1)));case"textarea":for(s in h=p=null,n)if(a=n[s],n.hasOwnProperty(s)&&null!=a&&!r.hasOwnProperty(s))switch(s){case"value":case"children":break;default:Zu(e,t,s,null,r,a)}for(l in r)if(a=r[l],o=n[l],r.hasOwnProperty(l)&&(null!=a||null!=o))switch(l){case"value":p=a;break;case"defaultValue":h=a;break;case"children":break;case"dangerouslySetInnerHTML":if(null!=a)throw Error(i(91));break;default:a!==o&&Zu(e,t,l,a,r,o)}return void wt(e,p,h);case"option":for(var m in n)if(p=n[m],n.hasOwnProperty(m)&&null!=p&&!r.hasOwnProperty(m))if("selected"===m)e.selected=!1;else Zu(e,t,m,null,r,p);for(c in r)if(p=r[c],h=n[c],r.hasOwnProperty(c)&&p!==h&&(null!=p||null!=h))if("selected"===c)e.selected=p&&"function"!=typeof p&&"symbol"!=typeof p;else Zu(e,t,c,p,r,h);return;case"img":case"link":case"area":case"base":case"br":case"col":case"embed":case"hr":case"keygen":case"meta":case"param":case"source":case"track":case"wbr":case"menuitem":for(var g in n)p=n[g],n.hasOwnProperty(g)&&null!=p&&!r.hasOwnProperty(g)&&Zu(e,t,g,null,r,p);for(u in r)if(p=r[u],h=n[u],r.hasOwnProperty(u)&&p!==h&&(null!=p||null!=h))switch(u){case"children":case"dangerouslySetInnerHTML":if(null!=p)throw Error(i(137,t));break;default:Zu(e,t,u,p,r,h)}return;default:if(Ct(t)){for(var b in n)p=n[b],n.hasOwnProperty(b)&&void 0!==p&&!r.hasOwnProperty(b)&&Ju(e,t,b,void 0,r,p);for(d in r)p=r[d],h=n[d],!r.hasOwnProperty(d)||p===h||void 0===p&&void 0===h||Ju(e,t,d,p,r,h);return}}for(var y in n)p=n[y],n.hasOwnProperty(y)&&null!=p&&!r.hasOwnProperty(y)&&Zu(e,t,y,null,r,p);for(f in r)p=r[f],h=n[f],!r.hasOwnProperty(f)||p===h||null==p&&null==h||Zu(e,t,f,p,r,h)}(r,e.type,n,t),r[Ne]=t}catch(a){uu(e,e.return,a)}}function hs(e){return 5===e.tag||3===e.tag||26===e.tag||27===e.tag&&pd(e.type)||4===e.tag}function ms(e){e:for(;;){for(;null===e.sibling;){if(null===e.return||hs(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;5!==e.tag&&6!==e.tag&&18!==e.tag;){if(27===e.tag&&pd(e.type))continue e;if(2&e.flags)continue e;if(null===e.child||4===e.tag)continue e;e.child.return=e,e=e.child}if(!(2&e.flags))return e.stateNode}}function gs(e,t,n){var r=e.tag;if(5===r||6===r)e=e.stateNode,t?(9===n.nodeType?n.body:"HTML"===n.nodeName?n.ownerDocument.body:n).insertBefore(e,t):((t=9===n.nodeType?n.body:"HTML"===n.nodeName?n.ownerDocument.body:n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Xu));else if(4!==r&&(27===r&&pd(e.type)&&(n=e.stateNode,t=null),null!==(e=e.child)))for(gs(e,t,n),e=e.sibling;null!==e;)gs(e,t,n),e=e.sibling}function bs(e,t,n){var r=e.tag;if(5===r||6===r)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&(27===r&&pd(e.type)&&(n=e.stateNode),null!==(e=e.child)))for(bs(e,t,n),e=e.sibling;null!==e;)bs(e,t,n),e=e.sibling}function ys(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,a=t.attributes;a.length;)t.removeAttributeNode(a[0]);ed(t,r,n),t[Me]=e,t[Ne]=n}catch(o){uu(e,e.return,o)}}var vs=!1,ws=!1,ks=!1,Ss="function"==typeof WeakSet?WeakSet:Set,xs=null;function _s(e,t,n){var r=n.flags;switch(n.tag){case 0:case 11:case 15:Bs(e,n),4&r&&is(5,n);break;case 1:if(Bs(e,n),4&r)if(e=n.stateNode,null===t)try{e.componentDidMount()}catch(i){uu(n,n.return,i)}else{var a=gl(n.type,t.memoizedProps);t=t.memoizedState;try{e.componentDidUpdate(a,t,e.__reactInternalSnapshotBeforeUpdate)}catch(l){uu(n,n.return,l)}}64&r&&ss(n),512&r&&us(n,n.return);break;case 3:if(Bs(e,n),64&r&&null!==(e=n.updateQueue)){if(t=null,null!==n.child)switch(n.child.tag){case 27:case 5:case 1:t=n.child.stateNode}try{po(e,t)}catch(i){uu(n,n.return,i)}}break;case 27:null===t&&4&r&&ys(n);case 26:case 5:Bs(e,n),null===t&&4&r&&fs(n),512&r&&us(n,n.return);break;case 12:Bs(e,n);break;case 13:Bs(e,n),4&r&&js(e,n),64&r&&(null!==(e=n.memoizedState)&&(null!==(e=e.dehydrated)&&function(e,t){var n=e.ownerDocument;if("$?"!==e.data||"complete"===n.readyState)t();else{var r=function(){t(),n.removeEventListener("DOMContentLoaded",r)};n.addEventListener("DOMContentLoaded",r),e._reactRetry=r}}(e,n=hu.bind(null,n))));break;case 22:if(!(r=null!==n.memoizedState||vs)){t=null!==t&&null!==t.memoizedState||ws,a=vs;var o=ws;vs=r,(ws=t)&&!o?Is(e,n,!!(8772&n.subtreeFlags)):Bs(e,n),vs=a,ws=o}break;case 30:break;default:Bs(e,n)}}function Es(e){var t=e.alternate;null!==t&&(e.alternate=null,Es(t)),e.child=null,e.deletions=null,e.sibling=null,5===e.tag&&(null!==(t=e.stateNode)&&ze(t)),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}var Cs=null,As=!1;function Ls(e,t,n){for(n=n.child;null!==n;)Ts(e,t,n),n=n.sibling}function Ts(e,t,n){if(de&&"function"==typeof de.onCommitFiberUnmount)try{de.onCommitFiberUnmount(ue,n)}catch(o){}switch(n.tag){case 26:ws||ds(n,t),Ls(e,t,n),n.memoizedState?n.memoizedState.count--:n.stateNode&&(n=n.stateNode).parentNode.removeChild(n);break;case 27:ws||ds(n,t);var r=Cs,a=As;pd(n.type)&&(Cs=n.stateNode,As=!1),Ls(e,t,n),kd(n.stateNode),Cs=r,As=a;break;case 5:ws||ds(n,t);case 6:if(r=Cs,a=As,Cs=null,Ls(e,t,n),As=a,null!==(Cs=r))if(As)try{(9===Cs.nodeType?Cs.body:"HTML"===Cs.nodeName?Cs.ownerDocument.body:Cs).removeChild(n.stateNode)}catch(i){uu(n,t,i)}else try{Cs.removeChild(n.stateNode)}catch(i){uu(n,t,i)}break;case 18:null!==Cs&&(As?(hd(9===(e=Cs).nodeType?e.body:"HTML"===e.nodeName?e.ownerDocument.body:e,n.stateNode),Lf(e)):hd(Cs,n.stateNode));break;case 4:r=Cs,a=As,Cs=n.stateNode.containerInfo,As=!0,Ls(e,t,n),Cs=r,As=a;break;case 0:case 11:case 14:case 15:ws||ls(2,n,t),ws||ls(4,n,t),Ls(e,t,n);break;case 1:ws||(ds(n,t),"function"==typeof(r=n.stateNode).componentWillUnmount&&cs(n,t,r)),Ls(e,t,n);break;case 21:Ls(e,t,n);break;case 22:ws=(r=ws)||null!==n.memoizedState,Ls(e,t,n),ws=r;break;default:Ls(e,t,n)}}function js(e,t){if(null===t.memoizedState&&(null!==(e=t.alternate)&&(null!==(e=e.memoizedState)&&null!==(e=e.dehydrated))))try{Lf(e)}catch(n){uu(t,t.return,n)}}function Ps(e,t){var n=function(e){switch(e.tag){case 13:case 19:var t=e.stateNode;return null===t&&(t=e.stateNode=new Ss),t;case 22:return null===(t=(e=e.stateNode)._retryCache)&&(t=e._retryCache=new Ss),t;default:throw Error(i(435,e.tag))}}(e);t.forEach(function(t){var r=mu.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))})}function Ms(e,t){var n=t.deletions;if(null!==n)for(var r=0;r<n.length;r++){var a=n[r],o=e,l=t,s=l;e:for(;null!==s;){switch(s.tag){case 27:if(pd(s.type)){Cs=s.stateNode,As=!1;break e}break;case 5:Cs=s.stateNode,As=!1;break e;case 3:case 4:Cs=s.stateNode.containerInfo,As=!0;break e}s=s.return}if(null===Cs)throw Error(i(160));Ts(o,l,a),Cs=null,As=!1,null!==(o=a.alternate)&&(o.return=null),a.return=null}if(13878&t.subtreeFlags)for(t=t.child;null!==t;)Os(t,e),t=t.sibling}var Ns=null;function Os(e,t){var n=e.alternate,r=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:Ms(t,e),Rs(e),4&r&&(ls(3,e,e.return),is(3,e),ls(5,e,e.return));break;case 1:Ms(t,e),Rs(e),512&r&&(ws||null===n||ds(n,n.return)),64&r&&vs&&(null!==(e=e.updateQueue)&&(null!==(r=e.callbacks)&&(n=e.shared.hiddenCallbacks,e.shared.hiddenCallbacks=null===n?r:n.concat(r))));break;case 26:var a=Ns;if(Ms(t,e),Rs(e),512&r&&(ws||null===n||ds(n,n.return)),4&r){var o=null!==n?n.memoizedState:null;if(r=e.memoizedState,null===n)if(null===r)if(null===e.stateNode){e:{r=e.type,n=e.memoizedProps,a=a.ownerDocument||a;t:switch(r){case"title":(!(o=a.getElementsByTagName("title")[0])||o[Ie]||o[Me]||"http://www.w3.org/2000/svg"===o.namespaceURI||o.hasAttribute("itemprop"))&&(o=a.createElement(r),a.head.insertBefore(o,a.querySelector("head > title"))),ed(o,r,n),o[Me]=e,Ge(o),r=o;break e;case"link":var l=Id("link","href",a).get(r+(n.href||""));if(l)for(var s=0;s<l.length;s++)if((o=l[s]).getAttribute("href")===(null==n.href||""===n.href?null:n.href)&&o.getAttribute("rel")===(null==n.rel?null:n.rel)&&o.getAttribute("title")===(null==n.title?null:n.title)&&o.getAttribute("crossorigin")===(null==n.crossOrigin?null:n.crossOrigin)){l.splice(s,1);break t}ed(o=a.createElement(r),r,n),a.head.appendChild(o);break;case"meta":if(l=Id("meta","content",a).get(r+(n.content||"")))for(s=0;s<l.length;s++)if((o=l[s]).getAttribute("content")===(null==n.content?null:""+n.content)&&o.getAttribute("name")===(null==n.name?null:n.name)&&o.getAttribute("property")===(null==n.property?null:n.property)&&o.getAttribute("http-equiv")===(null==n.httpEquiv?null:n.httpEquiv)&&o.getAttribute("charset")===(null==n.charSet?null:n.charSet)){l.splice(s,1);break t}ed(o=a.createElement(r),r,n),a.head.appendChild(o);break;default:throw Error(i(468,r))}o[Me]=e,Ge(o),r=o}e.stateNode=r}else zd(a,e.type,e.stateNode);else e.stateNode=Od(a,r,e.memoizedProps);else o!==r?(null===o?null!==n.stateNode&&(n=n.stateNode).parentNode.removeChild(n):o.count--,null===r?zd(a,e.type,e.stateNode):Od(a,r,e.memoizedProps)):null===r&&null!==e.stateNode&&ps(e,e.memoizedProps,n.memoizedProps)}break;case 27:Ms(t,e),Rs(e),512&r&&(ws||null===n||ds(n,n.return)),null!==n&&4&r&&ps(e,e.memoizedProps,n.memoizedProps);break;case 5:if(Ms(t,e),Rs(e),512&r&&(ws||null===n||ds(n,n.return)),32&e.flags){a=e.stateNode;try{St(a,"")}catch(h){uu(e,e.return,h)}}4&r&&null!=e.stateNode&&ps(e,a=e.memoizedProps,null!==n?n.memoizedProps:a),1024&r&&(ks=!0);break;case 6:if(Ms(t,e),Rs(e),4&r){if(null===e.stateNode)throw Error(i(162));r=e.memoizedProps,n=e.stateNode;try{n.nodeValue=r}catch(h){uu(e,e.return,h)}}break;case 3:if(Fd=null,a=Ns,Ns=_d(t.containerInfo),Ms(t,e),Ns=a,Rs(e),4&r&&null!==n&&n.memoizedState.isDehydrated)try{Lf(t.containerInfo)}catch(h){uu(e,e.return,h)}ks&&(ks=!1,Ds(e));break;case 4:r=Ns,Ns=_d(e.stateNode.containerInfo),Ms(t,e),Rs(e),Ns=r;break;case 12:default:Ms(t,e),Rs(e);break;case 13:Ms(t,e),Rs(e),8192&e.child.flags&&null!==e.memoizedState!=(null!==n&&null!==n.memoizedState)&&(kc=te()),4&r&&(null!==(r=e.updateQueue)&&(e.updateQueue=null,Ps(e,r)));break;case 22:a=null!==e.memoizedState;var c=null!==n&&null!==n.memoizedState,u=vs,d=ws;if(vs=u||a,ws=d||c,Ms(t,e),ws=d,vs=u,Rs(e),8192&r)e:for(t=e.stateNode,t._visibility=a?-2&t._visibility:1|t._visibility,a&&(null===n||c||vs||ws||Fs(e)),n=null,t=e;;){if(5===t.tag||26===t.tag){if(null===n){c=n=t;try{if(o=c.stateNode,a)"function"==typeof(l=o.style).setProperty?l.setProperty("display","none","important"):l.display="none";else{s=c.stateNode;var f=c.memoizedProps.style,p=null!=f&&f.hasOwnProperty("display")?f.display:null;s.style.display=null==p||"boolean"==typeof p?"":(""+p).trim()}}catch(h){uu(c,c.return,h)}}}else if(6===t.tag){if(null===n){c=t;try{c.stateNode.nodeValue=a?"":c.memoizedProps}catch(h){uu(c,c.return,h)}}}else if((22!==t.tag&&23!==t.tag||null===t.memoizedState||t===e)&&null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break e;for(;null===t.sibling;){if(null===t.return||t.return===e)break e;n===t&&(n=null),t=t.return}n===t&&(n=null),t.sibling.return=t.return,t=t.sibling}4&r&&(null!==(r=e.updateQueue)&&(null!==(n=r.retryQueue)&&(r.retryQueue=null,Ps(e,n))));break;case 19:Ms(t,e),Rs(e),4&r&&(null!==(r=e.updateQueue)&&(e.updateQueue=null,Ps(e,r)));case 30:case 21:}}function Rs(e){var t=e.flags;if(2&t){try{for(var n,r=e.return;null!==r;){if(hs(r)){n=r;break}r=r.return}if(null==n)throw Error(i(160));switch(n.tag){case 27:var a=n.stateNode;bs(e,ms(e),a);break;case 5:var o=n.stateNode;32&n.flags&&(St(o,""),n.flags&=-33),bs(e,ms(e),o);break;case 3:case 4:var l=n.stateNode.containerInfo;gs(e,ms(e),l);break;default:throw Error(i(161))}}catch(s){uu(e,e.return,s)}e.flags&=-3}4096&t&&(e.flags&=-4097)}function Ds(e){if(1024&e.subtreeFlags)for(e=e.child;null!==e;){var t=e;Ds(t),5===t.tag&&1024&t.flags&&t.stateNode.reset(),e=e.sibling}}function Bs(e,t){if(8772&t.subtreeFlags)for(t=t.child;null!==t;)_s(e,t.alternate,t),t=t.sibling}function Fs(e){for(e=e.child;null!==e;){var t=e;switch(t.tag){case 0:case 11:case 14:case 15:ls(4,t,t.return),Fs(t);break;case 1:ds(t,t.return);var n=t.stateNode;"function"==typeof n.componentWillUnmount&&cs(t,t.return,n),Fs(t);break;case 27:kd(t.stateNode);case 26:case 5:ds(t,t.return),Fs(t);break;case 22:null===t.memoizedState&&Fs(t);break;default:Fs(t)}e=e.sibling}}function Is(e,t,n){for(n=n&&!!(8772&t.subtreeFlags),t=t.child;null!==t;){var r=t.alternate,a=e,o=t,i=o.flags;switch(o.tag){case 0:case 11:case 15:Is(a,o,n),is(4,o);break;case 1:if(Is(a,o,n),"function"==typeof(a=(r=o).stateNode).componentDidMount)try{a.componentDidMount()}catch(c){uu(r,r.return,c)}if(null!==(a=(r=o).updateQueue)){var l=r.stateNode;try{var s=a.shared.hiddenCallbacks;if(null!==s)for(a.shared.hiddenCallbacks=null,a=0;a<s.length;a++)fo(s[a],l)}catch(c){uu(r,r.return,c)}}n&&64&i&&ss(o),us(o,o.return);break;case 27:ys(o);case 26:case 5:Is(a,o,n),n&&null===r&&4&i&&fs(o),us(o,o.return);break;case 12:Is(a,o,n);break;case 13:Is(a,o,n),n&&4&i&&js(a,o);break;case 22:null===o.memoizedState&&Is(a,o,n),us(o,o.return);break;case 30:break;default:Is(a,o,n)}t=t.sibling}}function zs(e,t){var n=null;null!==e&&null!==e.memoizedState&&null!==e.memoizedState.cachePool&&(n=e.memoizedState.cachePool.pool),e=null,null!==t.memoizedState&&null!==t.memoizedState.cachePool&&(e=t.memoizedState.cachePool.pool),e!==n&&(null!=e&&e.refCount++,null!=n&&Oa(n))}function $s(e,t){e=null,null!==t.alternate&&(e=t.alternate.memoizedState.cache),(t=t.memoizedState.cache)!==e&&(t.refCount++,null!=e&&Oa(e))}function Us(e,t,n,r){if(10256&t.subtreeFlags)for(t=t.child;null!==t;)qs(e,t,n,r),t=t.sibling}function qs(e,t,n,r){var a=t.flags;switch(t.tag){case 0:case 11:case 15:Us(e,t,n,r),2048&a&&is(9,t);break;case 1:case 13:default:Us(e,t,n,r);break;case 3:Us(e,t,n,r),2048&a&&(e=null,null!==t.alternate&&(e=t.alternate.memoizedState.cache),(t=t.memoizedState.cache)!==e&&(t.refCount++,null!=e&&Oa(e)));break;case 12:if(2048&a){Us(e,t,n,r),e=t.stateNode;try{var o=t.memoizedProps,i=o.id,l=o.onPostCommit;"function"==typeof l&&l(i,null===t.alternate?"mount":"update",e.passiveEffectDuration,-0)}catch(s){uu(t,t.return,s)}}else Us(e,t,n,r);break;case 23:break;case 22:o=t.stateNode,i=t.alternate,null!==t.memoizedState?2&o._visibility?Us(e,t,n,r):Gs(e,t):2&o._visibility?Us(e,t,n,r):(o._visibility|=2,Hs(e,t,n,r,!!(10256&t.subtreeFlags))),2048&a&&zs(i,t);break;case 24:Us(e,t,n,r),2048&a&&$s(t.alternate,t)}}function Hs(e,t,n,r,a){for(a=a&&!!(10256&t.subtreeFlags),t=t.child;null!==t;){var o=e,i=t,l=n,s=r,c=i.flags;switch(i.tag){case 0:case 11:case 15:Hs(o,i,l,s,a),is(8,i);break;case 23:break;case 22:var u=i.stateNode;null!==i.memoizedState?2&u._visibility?Hs(o,i,l,s,a):Gs(o,i):(u._visibility|=2,Hs(o,i,l,s,a)),a&&2048&c&&zs(i.alternate,i);break;case 24:Hs(o,i,l,s,a),a&&2048&c&&$s(i.alternate,i);break;default:Hs(o,i,l,s,a)}t=t.sibling}}function Gs(e,t){if(10256&t.subtreeFlags)for(t=t.child;null!==t;){var n=e,r=t,a=r.flags;switch(r.tag){case 22:Gs(n,r),2048&a&&zs(r.alternate,r);break;case 24:Gs(n,r),2048&a&&$s(r.alternate,r);break;default:Gs(n,r)}t=t.sibling}}var Vs=8192;function Ws(e){if(e.subtreeFlags&Vs)for(e=e.child;null!==e;)Qs(e),e=e.sibling}function Qs(e){switch(e.tag){case 26:Ws(e),e.flags&Vs&&null!==e.memoizedState&&function(e,t,n){if(null===Ud)throw Error(i(475));var r=Ud;if(!("stylesheet"!==t.type||"string"==typeof n.media&&!1===matchMedia(n.media).matches||4&t.state.loading)){if(null===t.instance){var a=Td(n.href),o=e.querySelector(jd(a));if(o)return null!==(e=o._p)&&"object"==typeof e&&"function"==typeof e.then&&(r.count++,r=Hd.bind(r),e.then(r,r)),t.state.loading|=4,t.instance=o,void Ge(o);o=e.ownerDocument||e,n=Pd(n),(a=Sd.get(a))&&Dd(n,a),Ge(o=o.createElement("link"));var l=o;l._p=new Promise(function(e,t){l.onload=e,l.onerror=t}),ed(o,"link",n),t.instance=o}null===r.stylesheets&&(r.stylesheets=new Map),r.stylesheets.set(t,e),(e=t.state.preload)&&!(3&t.state.loading)&&(r.count++,t=Hd.bind(r),e.addEventListener("load",t),e.addEventListener("error",t))}}(Ns,e.memoizedState,e.memoizedProps);break;case 5:default:Ws(e);break;case 3:case 4:var t=Ns;Ns=_d(e.stateNode.containerInfo),Ws(e),Ns=t;break;case 22:null===e.memoizedState&&(null!==(t=e.alternate)&&null!==t.memoizedState?(t=Vs,Vs=16777216,Ws(e),Vs=t):Ws(e))}}function Ks(e){var t=e.alternate;if(null!==t&&null!==(e=t.child)){t.child=null;do{t=e.sibling,e.sibling=null,e=t}while(null!==e)}}function Ys(e){var t=e.deletions;if(16&e.flags){if(null!==t)for(var n=0;n<t.length;n++){var r=t[n];xs=r,Js(r,e)}Ks(e)}if(10256&e.subtreeFlags)for(e=e.child;null!==e;)Xs(e),e=e.sibling}function Xs(e){switch(e.tag){case 0:case 11:case 15:Ys(e),2048&e.flags&&ls(9,e,e.return);break;case 3:case 12:default:Ys(e);break;case 22:var t=e.stateNode;null!==e.memoizedState&&2&t._visibility&&(null===e.return||13!==e.return.tag)?(t._visibility&=-3,Zs(e)):Ys(e)}}function Zs(e){var t=e.deletions;if(16&e.flags){if(null!==t)for(var n=0;n<t.length;n++){var r=t[n];xs=r,Js(r,e)}Ks(e)}for(e=e.child;null!==e;){switch((t=e).tag){case 0:case 11:case 15:ls(8,t,t.return),Zs(t);break;case 22:2&(n=t.stateNode)._visibility&&(n._visibility&=-3,Zs(t));break;default:Zs(t)}e=e.sibling}}function Js(e,t){for(;null!==xs;){var n=xs;switch(n.tag){case 0:case 11:case 15:ls(8,n,t);break;case 23:case 22:if(null!==n.memoizedState&&null!==n.memoizedState.cachePool){var r=n.memoizedState.cachePool.pool;null!=r&&r.refCount++}break;case 24:Oa(n.memoizedState.cache)}if(null!==(r=n.child))r.return=n,xs=r;else e:for(n=e;null!==xs;){var a=(r=xs).sibling,o=r.return;if(Es(r),r===n){xs=null;break e}if(null!==a){a.return=o,xs=a;break e}xs=o}}}var ec={getCacheForType:function(e){var t=Ca(Ma),n=t.data.get(e);return void 0===n&&(n=e(),t.data.set(e,n)),n}},tc="function"==typeof WeakMap?WeakMap:Map,nc=0,rc=null,ac=null,oc=0,ic=0,lc=null,sc=!1,cc=!1,uc=!1,dc=0,fc=0,pc=0,hc=0,mc=0,gc=0,bc=0,yc=null,vc=null,wc=!1,kc=0,Sc=1/0,xc=null,_c=null,Ec=0,Cc=null,Ac=null,Lc=0,Tc=0,jc=null,Pc=null,Mc=0,Nc=null;function Oc(){if(2&nc&&0!==oc)return oc&-oc;if(null!==O.T){return 0!==Ba?Ba:Tu()}return je()}function Rc(){0===gc&&(gc=536870912&oc&&!oa?536870912:Se());var e=al.current;return null!==e&&(e.flags|=32),gc}function Dc(e,t,n){(e!==rc||2!==ic&&9!==ic)&&null===e.cancelPendingCommit||(qc(e,0),zc(e,oc,gc,!1)),Ee(e,n),2&nc&&e===rc||(e===rc&&(!(2&nc)&&(hc|=n),4===fc&&zc(e,oc,gc,!1)),Su(e))}function Bc(e,t,n){if(6&nc)throw Error(i(327));for(var r=!n&&!(124&t)&&0===(t&e.expiredLanes)||we(e,t),a=r?function(e,t){var n=nc;nc|=2;var r=Gc(),a=Vc();rc!==e||oc!==t?(xc=null,Sc=te()+500,qc(e,t)):cc=we(e,t);e:for(;;)try{if(0!==ic&&null!==ac){t=ac;var o=lc;t:switch(ic){case 1:ic=0,lc=null,Jc(e,t,o,1);break;case 2:case 9:if(Ka(o)){ic=0,lc=null,Zc(t);break}t=function(){2!==ic&&9!==ic||rc!==e||(ic=7),Su(e)},o.then(t,t);break e;case 3:ic=7;break e;case 4:ic=5;break e;case 7:Ka(o)?(ic=0,lc=null,Zc(t)):(ic=0,lc=null,Jc(e,t,o,7));break;case 5:var l=null;switch(ac.tag){case 26:l=ac.memoizedState;case 5:case 27:var s=ac;if(!l||$d(l)){ic=0,lc=null;var c=s.sibling;if(null!==c)ac=c;else{var u=s.return;null!==u?(ac=u,eu(u)):ac=null}break t}}ic=0,lc=null,Jc(e,t,o,5);break;case 6:ic=0,lc=null,Jc(e,t,o,6);break;case 8:Uc(),fc=6;break e;default:throw Error(i(462))}}Yc();break}catch(d){Hc(e,d)}return ya=ba=null,O.H=r,O.A=a,nc=n,null!==ac?0:(rc=null,oc=0,Lr(),fc)}(e,t):Qc(e,t,!0),o=r;;){if(0===a){cc&&!r&&zc(e,t,0,!1);break}if(n=e.current.alternate,!o||Ic(n)){if(2===a){if(o=t,e.errorRecoveryDisabledLanes&o)var l=0;else l=0!==(l=-536870913&e.pendingLanes)?l:536870912&l?536870912:0;if(0!==l){t=l;e:{var s=e;a=yc;var c=s.current.memoizedState.isDehydrated;if(c&&(qc(s,l).flags|=256),2!==(l=Qc(s,l,!1))){if(uc&&!c){s.errorRecoveryDisabledLanes|=o,hc|=o,a=4;break e}o=vc,vc=a,null!==o&&(null===vc?vc=o:vc.push.apply(vc,o))}a=l}if(o=!1,2!==a)continue}}if(1===a){qc(e,0),zc(e,t,0,!0);break}e:{switch(r=e,o=a){case 0:case 1:throw Error(i(345));case 4:if((4194048&t)!==t)break;case 6:zc(r,t,gc,!sc);break e;case 2:vc=null;break;case 3:case 5:break;default:throw Error(i(329))}if((62914560&t)===t&&10<(a=kc+300-te())){if(zc(r,t,gc,!sc),0!==ve(r,0,!0))break e;r.timeoutHandle=sd(Fc.bind(null,r,n,vc,xc,wc,t,gc,hc,bc,sc,o,2,-0,0),a)}else Fc(r,n,vc,xc,wc,t,gc,hc,bc,sc,o,0,-0,0)}break}a=Qc(e,t,!1),o=!1}Su(e)}function Fc(e,t,n,r,a,o,l,s,c,u,d,f,p,h){if(e.timeoutHandle=-1,(8192&(f=t.subtreeFlags)||!(16785408&~f))&&(Ud={stylesheets:null,count:0,unsuspend:qd},Qs(t),null!==(f=function(){if(null===Ud)throw Error(i(475));var e=Ud;return e.stylesheets&&0===e.count&&Vd(e,e.stylesheets),0<e.count?function(t){var n=setTimeout(function(){if(e.stylesheets&&Vd(e,e.stylesheets),e.unsuspend){var t=e.unsuspend;e.unsuspend=null,t()}},6e4);return e.unsuspend=t,function(){e.unsuspend=null,clearTimeout(n)}}:null}())))return e.cancelPendingCommit=f(nu.bind(null,e,t,o,n,r,a,l,s,c,d,1,p,h)),void zc(e,o,l,!u);nu(e,t,o,n,r,a,l,s,c)}function Ic(e){for(var t=e;;){var n=t.tag;if((0===n||11===n||15===n)&&16384&t.flags&&(null!==(n=t.updateQueue)&&null!==(n=n.stores)))for(var r=0;r<n.length;r++){var a=n[r],o=a.getSnapshot;a=a.value;try{if(!Kn(o(),a))return!1}catch(i){return!1}}if(n=t.child,16384&t.subtreeFlags&&null!==n)n.return=t,t=n;else{if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}function zc(e,t,n,r){t&=~mc,t&=~hc,e.suspendedLanes|=t,e.pingedLanes&=~t,r&&(e.warmLanes|=t),r=e.expirationTimes;for(var a=t;0<a;){var o=31-pe(a),i=1<<o;r[o]=-1,a&=~i}0!==n&&Ce(e,n,t)}function $c(){return!!(6&nc)||(xu(0,!1),!1)}function Uc(){if(null!==ac){if(0===ic)var e=ac.return;else ya=ba=null,Fo(e=ac),Ki=null,Yi=0,e=ac;for(;null!==e;)os(e.alternate,e),e=e.return;ac=null}}function qc(e,t){var n=e.timeoutHandle;-1!==n&&(e.timeoutHandle=-1,cd(n)),null!==(n=e.cancelPendingCommit)&&(e.cancelPendingCommit=null,n()),Uc(),rc=e,ac=n=Fr(e.current,null),oc=t,ic=0,lc=null,sc=!1,cc=we(e,t),uc=!1,bc=gc=mc=hc=pc=fc=0,vc=yc=null,wc=!1,8&t&&(t|=32&t);var r=e.entangledLanes;if(0!==r)for(e=e.entanglements,r&=t;0<r;){var a=31-pe(r),o=1<<a;t|=e[a],r&=~o}return dc=t,Lr(),n}function Hc(e,t){wo=null,O.H=Gi,t===Ga||t===Wa?(t=Ja(),ic=3):t===Va?(t=Ja(),ic=4):ic=t===Cl?8:null!==t&&"object"==typeof t&&"function"==typeof t.then?6:1,lc=t,null===ac&&(fc=1,kl(e,_r(t,e.current)))}function Gc(){var e=O.H;return O.H=Gi,null===e?Gi:e}function Vc(){var e=O.A;return O.A=ec,e}function Wc(){fc=4,sc||(4194048&oc)!==oc&&null!==al.current||(cc=!0),!(134217727&pc)&&!(134217727&hc)||null===rc||zc(rc,oc,gc,!1)}function Qc(e,t,n){var r=nc;nc|=2;var a=Gc(),o=Vc();rc===e&&oc===t||(xc=null,qc(e,t)),t=!1;var i=fc;e:for(;;)try{if(0!==ic&&null!==ac){var l=ac,s=lc;switch(ic){case 8:Uc(),i=6;break e;case 3:case 2:case 9:case 6:null===al.current&&(t=!0);var c=ic;if(ic=0,lc=null,Jc(e,l,s,c),n&&cc){i=0;break e}break;default:c=ic,ic=0,lc=null,Jc(e,l,s,c)}}Kc(),i=fc;break}catch(u){Hc(e,u)}return t&&e.shellSuspendCounter++,ya=ba=null,nc=r,O.H=a,O.A=o,null===ac&&(rc=null,oc=0,Lr()),i}function Kc(){for(;null!==ac;)Xc(ac)}function Yc(){for(;null!==ac&&!J();)Xc(ac)}function Xc(e){var t=Xl(e.alternate,e,dc);e.memoizedProps=e.pendingProps,null===t?eu(e):ac=t}function Zc(e){var t=e,n=t.alternate;switch(t.tag){case 15:case 0:t=Dl(n,t,t.pendingProps,t.type,void 0,oc);break;case 11:t=Dl(n,t,t.pendingProps,t.type.render,t.ref,oc);break;case 5:Fo(t);default:os(n,t),t=Xl(n,t=ac=Ir(t,dc),dc)}e.memoizedProps=e.pendingProps,null===t?eu(e):ac=t}function Jc(e,t,n,r){ya=ba=null,Fo(t),Ki=null,Yi=0;var a=t.return;try{if(function(e,t,n,r,a){if(n.flags|=32768,null!==r&&"object"==typeof r&&"function"==typeof r.then){if(null!==(t=n.alternate)&&xa(t,n,a,!0),null!==(n=al.current)){switch(n.tag){case 13:return null===ol?Wc():null===n.alternate&&0===fc&&(fc=3),n.flags&=-257,n.flags|=65536,n.lanes=a,r===Qa?n.flags|=16384:(null===(t=n.updateQueue)?n.updateQueue=new Set([r]):t.add(r),du(e,r,a)),!1;case 22:return n.flags|=65536,r===Qa?n.flags|=16384:(null===(t=n.updateQueue)?(t={transitions:null,markerInstances:null,retryQueue:new Set([r])},n.updateQueue=t):null===(n=t.retryQueue)?t.retryQueue=new Set([r]):n.add(r),du(e,r,a)),!1}throw Error(i(435,n.tag))}return du(e,r,a),Wc(),!1}if(oa)return null!==(t=al.current)?(!(65536&t.flags)&&(t.flags|=256),t.flags|=65536,t.lanes=a,r!==sa&&ma(_r(e=Error(i(422),{cause:r}),n))):(r!==sa&&ma(_r(t=Error(i(423),{cause:r}),n)),(e=e.current.alternate).flags|=65536,a&=-a,e.lanes|=a,r=_r(r,n),lo(e,a=xl(e.stateNode,r,a)),4!==fc&&(fc=2)),!1;var o=Error(i(520),{cause:r});if(o=_r(o,n),null===yc?yc=[o]:yc.push(o),4!==fc&&(fc=2),null===t)return!0;r=_r(r,n),n=t;do{switch(n.tag){case 3:return n.flags|=65536,e=a&-a,n.lanes|=e,lo(n,e=xl(n.stateNode,r,e)),!1;case 1:if(t=n.type,o=n.stateNode,!(128&n.flags||"function"!=typeof t.getDerivedStateFromError&&(null===o||"function"!=typeof o.componentDidCatch||null!==_c&&_c.has(o))))return n.flags|=65536,a&=-a,n.lanes|=a,El(a=_l(a),e,n,r),lo(n,a),!1}n=n.return}while(null!==n);return!1}(e,a,t,n,oc))return fc=1,kl(e,_r(n,e.current)),void(ac=null)}catch(o){if(null!==a)throw ac=a,o;return fc=1,kl(e,_r(n,e.current)),void(ac=null)}32768&t.flags?(oa||1===r?e=!0:cc||536870912&oc?e=!1:(sc=e=!0,(2===r||9===r||3===r||6===r)&&(null!==(r=al.current)&&13===r.tag&&(r.flags|=16384))),tu(t,e)):eu(t)}function eu(e){var t=e;do{if(32768&t.flags)return void tu(t,sc);e=t.return;var n=rs(t.alternate,t,dc);if(null!==n)return void(ac=n);if(null!==(t=t.sibling))return void(ac=t);ac=t=e}while(null!==t);0===fc&&(fc=5)}function tu(e,t){do{var n=as(e.alternate,e);if(null!==n)return n.flags&=32767,void(ac=n);if(null!==(n=e.return)&&(n.flags|=32768,n.subtreeFlags=0,n.deletions=null),!t&&null!==(e=e.sibling))return void(ac=e);ac=e=n}while(null!==e);fc=6,ac=null}function nu(e,t,n,r,a,o,l,s,c){e.cancelPendingCommit=null;do{lu()}while(0!==Ec);if(6&nc)throw Error(i(327));if(null!==t){if(t===e.current)throw Error(i(177));if(o=t.lanes|t.childLanes,function(e,t,n,r,a,o){var i=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var l=e.entanglements,s=e.expirationTimes,c=e.hiddenUpdates;for(n=i&~n;0<n;){var u=31-pe(n),d=1<<u;l[u]=0,s[u]=-1;var f=c[u];if(null!==f)for(c[u]=null,u=0;u<f.length;u++){var p=f[u];null!==p&&(p.lane&=-536870913)}n&=~d}0!==r&&Ce(e,r,0),0!==o&&0===a&&0!==e.tag&&(e.suspendedLanes|=o&~(i&~t))}(e,n,o|=Ar,l,s,c),e===rc&&(ac=rc=null,oc=0),Ac=t,Cc=e,Lc=n,Tc=o,jc=a,Pc=r,10256&t.subtreeFlags||10256&t.flags?(e.callbackNode=null,e.callbackPriority=0,X(oe,function(){return su(),null})):(e.callbackNode=null,e.callbackPriority=0),r=!!(13878&t.flags),13878&t.subtreeFlags||r){r=O.T,O.T=null,a=R.p,R.p=2,l=nc,nc|=4;try{!function(e,t){if(e=e.containerInfo,td=nf,tr(e=er(e))){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{var r=(n=(n=e.ownerDocument)&&n.defaultView||window).getSelection&&n.getSelection();if(r&&0!==r.rangeCount){n=r.anchorNode;var a=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch(g){n=null;break e}var l=0,s=-1,c=-1,u=0,d=0,f=e,p=null;t:for(;;){for(var h;f!==n||0!==a&&3!==f.nodeType||(s=l+a),f!==o||0!==r&&3!==f.nodeType||(c=l+r),3===f.nodeType&&(l+=f.nodeValue.length),null!==(h=f.firstChild);)p=f,f=h;for(;;){if(f===e)break t;if(p===n&&++u===a&&(s=l),p===o&&++d===r&&(c=l),null!==(h=f.nextSibling))break;p=(f=p).parentNode}f=h}n=-1===s||-1===c?null:{start:s,end:c}}else n=null}n=n||{start:0,end:0}}else n=null;for(nd={focusedElem:e,selectionRange:n},nf=!1,xs=t;null!==xs;)if(e=(t=xs).child,1024&t.subtreeFlags&&null!==e)e.return=t,xs=e;else for(;null!==xs;){switch(o=(t=xs).alternate,e=t.flags,t.tag){case 0:case 11:case 15:case 5:case 26:case 27:case 6:case 4:case 17:break;case 1:if(1024&e&&null!==o){e=void 0,n=t,a=o.memoizedProps,o=o.memoizedState,r=n.stateNode;try{var m=gl(n.type,a,(n.elementType,n.type));e=r.getSnapshotBeforeUpdate(m,o),r.__reactInternalSnapshotBeforeUpdate=e}catch(b){uu(n,n.return,b)}}break;case 3:if(1024&e)if(9===(n=(e=t.stateNode.containerInfo).nodeType))md(e);else if(1===n)switch(e.nodeName){case"HEAD":case"HTML":case"BODY":md(e);break;default:e.textContent=""}break;default:if(1024&e)throw Error(i(163))}if(null!==(e=t.sibling)){e.return=t.return,xs=e;break}xs=t.return}}(e,t)}finally{nc=l,R.p=a,O.T=r}}Ec=1,ru(),au(),ou()}}function ru(){if(1===Ec){Ec=0;var e=Cc,t=Ac,n=!!(13878&t.flags);if(13878&t.subtreeFlags||n){n=O.T,O.T=null;var r=R.p;R.p=2;var a=nc;nc|=4;try{Os(t,e);var o=nd,i=er(e.containerInfo),l=o.focusedElem,s=o.selectionRange;if(i!==l&&l&&l.ownerDocument&&Jn(l.ownerDocument.documentElement,l)){if(null!==s&&tr(l)){var c=s.start,u=s.end;if(void 0===u&&(u=c),"selectionStart"in l)l.selectionStart=c,l.selectionEnd=Math.min(u,l.value.length);else{var d=l.ownerDocument||document,f=d&&d.defaultView||window;if(f.getSelection){var p=f.getSelection(),h=l.textContent.length,m=Math.min(s.start,h),g=void 0===s.end?m:Math.min(s.end,h);!p.extend&&m>g&&(i=g,g=m,m=i);var b=Zn(l,m),y=Zn(l,g);if(b&&y&&(1!==p.rangeCount||p.anchorNode!==b.node||p.anchorOffset!==b.offset||p.focusNode!==y.node||p.focusOffset!==y.offset)){var v=d.createRange();v.setStart(b.node,b.offset),p.removeAllRanges(),m>g?(p.addRange(v),p.extend(y.node,y.offset)):(v.setEnd(y.node,y.offset),p.addRange(v))}}}}for(d=[],p=l;p=p.parentNode;)1===p.nodeType&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for("function"==typeof l.focus&&l.focus(),l=0;l<d.length;l++){var w=d[l];w.element.scrollLeft=w.left,w.element.scrollTop=w.top}}nf=!!td,nd=td=null}finally{nc=a,R.p=r,O.T=n}}e.current=t,Ec=2}}function au(){if(2===Ec){Ec=0;var e=Cc,t=Ac,n=!!(8772&t.flags);if(8772&t.subtreeFlags||n){n=O.T,O.T=null;var r=R.p;R.p=2;var a=nc;nc|=4;try{_s(e,t.alternate,t)}finally{nc=a,R.p=r,O.T=n}}Ec=3}}function ou(){if(4===Ec||3===Ec){Ec=0,ee();var e=Cc,t=Ac,n=Lc,r=Pc;10256&t.subtreeFlags||10256&t.flags?Ec=5:(Ec=0,Ac=Cc=null,iu(e,e.pendingLanes));var a=e.pendingLanes;if(0===a&&(_c=null),Te(n),t=t.stateNode,de&&"function"==typeof de.onCommitFiberRoot)try{de.onCommitFiberRoot(ue,t,void 0,!(128&~t.current.flags))}catch(s){}if(null!==r){t=O.T,a=R.p,R.p=2,O.T=null;try{for(var o=e.onRecoverableError,i=0;i<r.length;i++){var l=r[i];o(l.value,{componentStack:l.stack})}}finally{O.T=t,R.p=a}}3&Lc&&lu(),Su(e),a=e.pendingLanes,4194090&n&&42&a?e===Nc?Mc++:(Mc=0,Nc=e):Mc=0,xu(0,!1)}}function iu(e,t){0===(e.pooledCacheLanes&=t)&&(null!=(t=e.pooledCache)&&(e.pooledCache=null,Oa(t)))}function lu(e){return ru(),au(),ou(),su()}function su(){if(5!==Ec)return!1;var e=Cc,t=Tc;Tc=0;var n=Te(Lc),r=O.T,a=R.p;try{R.p=32>n?32:n,O.T=null,n=jc,jc=null;var o=Cc,l=Lc;if(Ec=0,Ac=Cc=null,Lc=0,6&nc)throw Error(i(331));var s=nc;if(nc|=4,Xs(o.current),qs(o,o.current,l,n),nc=s,xu(0,!1),de&&"function"==typeof de.onPostCommitFiberRoot)try{de.onPostCommitFiberRoot(ue,o)}catch(c){}return!0}finally{R.p=a,O.T=r,iu(e,t)}}function cu(e,t,n){t=_r(n,t),null!==(e=oo(e,t=xl(e.stateNode,t,2),2))&&(Ee(e,2),Su(e))}function uu(e,t,n){if(3===e.tag)cu(e,e,n);else for(;null!==t;){if(3===t.tag){cu(t,e,n);break}if(1===t.tag){var r=t.stateNode;if("function"==typeof t.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===_c||!_c.has(r))){e=_r(n,e),null!==(r=oo(t,n=_l(2),2))&&(El(n,r,t,e),Ee(r,2),Su(r));break}}t=t.return}}function du(e,t,n){var r=e.pingCache;if(null===r){r=e.pingCache=new tc;var a=new Set;r.set(t,a)}else void 0===(a=r.get(t))&&(a=new Set,r.set(t,a));a.has(n)||(uc=!0,a.add(n),e=fu.bind(null,e,t,n),t.then(e,e))}function fu(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,rc===e&&(oc&n)===n&&(4===fc||3===fc&&(62914560&oc)===oc&&300>te()-kc?!(2&nc)&&qc(e,0):mc|=n,bc===oc&&(bc=0)),Su(e)}function pu(e,t){0===t&&(t=xe()),null!==(e=Pr(e,t))&&(Ee(e,t),Su(e))}function hu(e){var t=e.memoizedState,n=0;null!==t&&(n=t.retryLane),pu(e,n)}function mu(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,a=e.memoizedState;null!==a&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}null!==r&&r.delete(t),pu(e,n)}var gu=null,bu=null,yu=!1,vu=!1,wu=!1,ku=0;function Su(e){e!==bu&&null===e.next&&(null===bu?gu=bu=e:bu=bu.next=e),vu=!0,yu||(yu=!0,dd(function(){6&nc?X(re,_u):Eu()}))}function xu(e,t){if(!wu&&vu){wu=!0;do{for(var n=!1,r=gu;null!==r;){if(!t)if(0!==e){var a=r.pendingLanes;if(0===a)var o=0;else{var i=r.suspendedLanes,l=r.pingedLanes;o=(1<<31-pe(42|e)+1)-1,o=201326741&(o&=a&~(i&~l))?201326741&o|1:o?2|o:0}0!==o&&(n=!0,Lu(r,o))}else o=oc,!(3&(o=ve(r,r===rc?o:0,null!==r.cancelPendingCommit||-1!==r.timeoutHandle)))||we(r,o)||(n=!0,Lu(r,o));r=r.next}}while(n);wu=!1}}function _u(){Eu()}function Eu(){vu=yu=!1;var e=0;0!==ku&&(function(){var e=window.event;if(e&&"popstate"===e.type)return e!==ld&&(ld=e,!0);return ld=null,!1}()&&(e=ku),ku=0);for(var t=te(),n=null,r=gu;null!==r;){var a=r.next,o=Cu(r,t);0===o?(r.next=null,null===n?gu=a:n.next=a,null===a&&(bu=n)):(n=r,(0!==e||3&o)&&(vu=!0)),r=a}xu(e,!1)}function Cu(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,a=e.expirationTimes,o=-62914561&e.pendingLanes;0<o;){var i=31-pe(o),l=1<<i,s=a[i];-1===s?0!==(l&n)&&0===(l&r)||(a[i]=ke(l,t)):s<=t&&(e.expiredLanes|=l),o&=~l}if(n=oc,n=ve(e,e===(t=rc)?n:0,null!==e.cancelPendingCommit||-1!==e.timeoutHandle),r=e.callbackNode,0===n||e===t&&(2===ic||9===ic)||null!==e.cancelPendingCommit)return null!==r&&null!==r&&Z(r),e.callbackNode=null,e.callbackPriority=0;if(!(3&n)||we(e,n)){if((t=n&-n)===e.callbackPriority)return t;switch(null!==r&&Z(r),Te(n)){case 2:case 8:n=ae;break;case 32:default:n=oe;break;case 268435456:n=le}return r=Au.bind(null,e),n=X(n,r),e.callbackPriority=t,e.callbackNode=n,t}return null!==r&&null!==r&&Z(r),e.callbackPriority=2,e.callbackNode=null,2}function Au(e,t){if(0!==Ec&&5!==Ec)return e.callbackNode=null,e.callbackPriority=0,null;var n=e.callbackNode;if(lu()&&e.callbackNode!==n)return null;var r=oc;return 0===(r=ve(e,e===rc?r:0,null!==e.cancelPendingCommit||-1!==e.timeoutHandle))?null:(Bc(e,r,t),Cu(e,te()),null!=e.callbackNode&&e.callbackNode===n?Au.bind(null,e):null)}function Lu(e,t){if(lu())return null;Bc(e,t,!0)}function Tu(){return 0===ku&&(ku=Se()),ku}function ju(e){return null==e||"symbol"==typeof e||"boolean"==typeof e?null:"function"==typeof e?e:Tt(""+e)}function Pu(e,t){var n=t.ownerDocument.createElement("input");return n.name=t.name,n.value=t.value,e.id&&n.setAttribute("form",e.id),t.parentNode.insertBefore(n,t),e=new FormData(e),n.parentNode.removeChild(n),e}for(var Mu=0;Mu<kr.length;Mu++){var Nu=kr[Mu];Sr(Nu.toLowerCase(),"on"+(Nu[0].toUpperCase()+Nu.slice(1)))}Sr(pr,"onAnimationEnd"),Sr(hr,"onAnimationIteration"),Sr(mr,"onAnimationStart"),Sr("dblclick","onDoubleClick"),Sr("focusin","onFocus"),Sr("focusout","onBlur"),Sr(gr,"onTransitionRun"),Sr(br,"onTransitionStart"),Sr(yr,"onTransitionCancel"),Sr(vr,"onTransitionEnd"),Ke("onMouseEnter",["mouseout","mouseover"]),Ke("onMouseLeave",["mouseout","mouseover"]),Ke("onPointerEnter",["pointerout","pointerover"]),Ke("onPointerLeave",["pointerout","pointerover"]),Qe("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),Qe("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),Qe("onBeforeInput",["compositionend","keypress","textInput","paste"]),Qe("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),Qe("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),Qe("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Ou="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Ru=new Set("beforetoggle cancel close invalid load scroll scrollend toggle".split(" ").concat(Ou));function Du(e,t){t=!!(4&t);for(var n=0;n<e.length;n++){var r=e[n],a=r.event;r=r.listeners;e:{var o=void 0;if(t)for(var i=r.length-1;0<=i;i--){var l=r[i],s=l.instance,c=l.currentTarget;if(l=l.listener,s!==o&&a.isPropagationStopped())break e;o=l,a.currentTarget=c;try{o(a)}catch(u){bl(u)}a.currentTarget=null,o=s}else for(i=0;i<r.length;i++){if(s=(l=r[i]).instance,c=l.currentTarget,l=l.listener,s!==o&&a.isPropagationStopped())break e;o=l,a.currentTarget=c;try{o(a)}catch(u){bl(u)}a.currentTarget=null,o=s}}}}function Bu(e,t){var n=t[Re];void 0===n&&(n=t[Re]=new Set);var r=e+"__bubble";n.has(r)||($u(t,e,2,!1),n.add(r))}function Fu(e,t,n){var r=0;t&&(r|=4),$u(n,e,r,t)}var Iu="_reactListening"+Math.random().toString(36).slice(2);function zu(e){if(!e[Iu]){e[Iu]=!0,Ve.forEach(function(t){"selectionchange"!==t&&(Ru.has(t)||Fu(t,!1,e),Fu(t,!0,e))});var t=9===e.nodeType?e:e.ownerDocument;null===t||t[Iu]||(t[Iu]=!0,Fu("selectionchange",!1,t))}}function $u(e,t,n,r){switch(uf(t)){case 2:var a=rf;break;case 8:a=af;break;default:a=of}n=a.bind(null,t,n,e),a=void 0,!It||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(a=!0),r?void 0!==a?e.addEventListener(t,n,{capture:!0,passive:a}):e.addEventListener(t,n,!0):void 0!==a?e.addEventListener(t,n,{passive:a}):e.addEventListener(t,n,!1)}function Uu(e,t,n,r,a){var o=r;if(!(1&t||2&t||null===r))e:for(;;){if(null===r)return;var i=r.tag;if(3===i||4===i){var l=r.stateNode.containerInfo;if(l===a)break;if(4===i)for(i=r.return;null!==i;){var c=i.tag;if((3===c||4===c)&&i.stateNode.containerInfo===a)return;i=i.return}for(;null!==l;){if(null===(i=$e(l)))return;if(5===(c=i.tag)||6===c||26===c||27===c){r=o=i;continue e}l=l.parentNode}}r=r.return}Dt(function(){var r=o,a=Pt(n),i=[];e:{var l=wr.get(e);if(void 0!==l){var c=Jt,u=e;switch(e){case"keypress":if(0===Gt(n))break e;case"keydown":case"keyup":c=mn;break;case"focusin":u="focus",c=on;break;case"focusout":u="blur",c=on;break;case"beforeblur":case"afterblur":c=on;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":c=rn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":c=an;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":c=bn;break;case pr:case hr:case mr:c=ln;break;case vr:c=yn;break;case"scroll":case"scrollend":c=tn;break;case"wheel":c=vn;break;case"copy":case"cut":case"paste":c=sn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":c=gn;break;case"toggle":case"beforetoggle":c=wn}var d=!!(4&t),f=!d&&("scroll"===e||"scrollend"===e),p=d?null!==l?l+"Capture":null:l;d=[];for(var h,m=r;null!==m;){var g=m;if(h=g.stateNode,5!==(g=g.tag)&&26!==g&&27!==g||null===h||null===p||null!=(g=Bt(m,p))&&d.push(qu(m,g,h)),f)break;m=m.return}0<d.length&&(l=new c(l,u,null,n,a),i.push({event:l,listeners:d}))}}if(!(7&t)){if(c="mouseout"===e||"pointerout"===e,(!(l="mouseover"===e||"pointerover"===e)||n===jt||!(u=n.relatedTarget||n.fromElement)||!$e(u)&&!u[Oe])&&(c||l)&&(l=a.window===a?a:(l=a.ownerDocument)?l.defaultView||l.parentWindow:window,c?(c=r,null!==(u=(u=n.relatedTarget||n.toElement)?$e(u):null)&&(f=s(u),d=u.tag,u!==f||5!==d&&27!==d&&6!==d)&&(u=null)):(c=null,u=r),c!==u)){if(d=rn,g="onMouseLeave",p="onMouseEnter",m="mouse","pointerout"!==e&&"pointerover"!==e||(d=gn,g="onPointerLeave",p="onPointerEnter",m="pointer"),f=null==c?l:qe(c),h=null==u?l:qe(u),(l=new d(g,m+"leave",c,n,a)).target=f,l.relatedTarget=h,g=null,$e(a)===r&&((d=new d(p,m+"enter",u,n,a)).target=h,d.relatedTarget=f,g=d),f=g,c&&u)e:{for(p=u,m=0,h=d=c;h;h=Gu(h))m++;for(h=0,g=p;g;g=Gu(g))h++;for(;0<m-h;)d=Gu(d),m--;for(;0<h-m;)p=Gu(p),h--;for(;m--;){if(d===p||null!==p&&d===p.alternate)break e;d=Gu(d),p=Gu(p)}d=null}else d=null;null!==c&&Vu(i,l,c,d,!1),null!==u&&null!==f&&Vu(i,f,u,d,!0)}if("select"===(c=(l=r?qe(r):window).nodeName&&l.nodeName.toLowerCase())||"input"===c&&"file"===l.type)var b=Fn;else if(Mn(l))if(In)b=Qn;else{b=Vn;var y=Gn}else!(c=l.nodeName)||"input"!==c.toLowerCase()||"checkbox"!==l.type&&"radio"!==l.type?r&&Ct(r.elementType)&&(b=Fn):b=Wn;switch(b&&(b=b(e,r))?Nn(i,b,n,a):(y&&y(e,l,r),"focusout"===e&&r&&"number"===l.type&&null!=r.memoizedProps.value&&yt(l,"number",l.value)),y=r?qe(r):window,e){case"focusin":(Mn(y)||"true"===y.contentEditable)&&(rr=y,ar=r,or=null);break;case"focusout":or=ar=rr=null;break;case"mousedown":ir=!0;break;case"contextmenu":case"mouseup":case"dragend":ir=!1,lr(i,n,a);break;case"selectionchange":if(nr)break;case"keydown":case"keyup":lr(i,n,a)}var v;if(Sn)e:{switch(e){case"compositionstart":var w="onCompositionStart";break e;case"compositionend":w="onCompositionEnd";break e;case"compositionupdate":w="onCompositionUpdate";break e}w=void 0}else jn?Ln(e,n)&&(w="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(w="onCompositionStart");w&&(En&&"ko"!==n.locale&&(jn||"onCompositionStart"!==w?"onCompositionEnd"===w&&jn&&(v=Ht()):(Ut="value"in($t=a)?$t.value:$t.textContent,jn=!0)),0<(y=Hu(r,w)).length&&(w=new cn(w,e,null,n,a),i.push({event:w,listeners:y}),v?w.data=v:null!==(v=Tn(n))&&(w.data=v))),(v=_n?function(e,t){switch(e){case"compositionend":return Tn(t);case"keypress":return 32!==t.which?null:(An=!0,Cn);case"textInput":return(e=t.data)===Cn&&An?null:e;default:return null}}(e,n):function(e,t){if(jn)return"compositionend"===e||!Sn&&Ln(e,t)?(e=Ht(),qt=Ut=$t=null,jn=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return En&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(w=Hu(r,"onBeforeInput")).length&&(y=new cn("onBeforeInput","beforeinput",null,n,a),i.push({event:y,listeners:w}),y.data=v)),function(e,t,n,r,a){if("submit"===t&&n&&n.stateNode===a){var o=ju((a[Ne]||null).action),i=r.submitter;i&&null!==(t=(t=i[Ne]||null)?ju(t.formAction):i.getAttribute("formAction"))&&(o=t,i=null);var l=new Jt("action","action",null,r,a);e.push({event:l,listeners:[{instance:null,listener:function(){if(r.defaultPrevented){if(0!==ku){var e=i?Pu(a,i):new FormData(a);Pi(n,{pending:!0,data:e,method:a.method,action:o},null,e)}}else"function"==typeof o&&(l.preventDefault(),e=i?Pu(a,i):new FormData(a),Pi(n,{pending:!0,data:e,method:a.method,action:o},o,e))},currentTarget:a}]})}}(i,e,r,n,a)}Du(i,t)})}function qu(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Hu(e,t){for(var n=t+"Capture",r=[];null!==e;){var a=e,o=a.stateNode;if(5!==(a=a.tag)&&26!==a&&27!==a||null===o||(null!=(a=Bt(e,n))&&r.unshift(qu(e,a,o)),null!=(a=Bt(e,t))&&r.push(qu(e,a,o))),3===e.tag)return r;e=e.return}return[]}function Gu(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag&&27!==e.tag);return e||null}function Vu(e,t,n,r,a){for(var o=t._reactName,i=[];null!==n&&n!==r;){var l=n,s=l.alternate,c=l.stateNode;if(l=l.tag,null!==s&&s===r)break;5!==l&&26!==l&&27!==l||null===c||(s=c,a?null!=(c=Bt(n,o))&&i.unshift(qu(n,c,s)):a||null!=(c=Bt(n,o))&&i.push(qu(n,c,s))),n=n.return}0!==i.length&&e.push({event:t,listeners:i})}var Wu=/\r\n?/g,Qu=/\u0000|\uFFFD/g;function Ku(e){return("string"==typeof e?e:""+e).replace(Wu,"\n").replace(Qu,"")}function Yu(e,t){return t=Ku(t),Ku(e)===t}function Xu(){}function Zu(e,t,n,r,a,o){switch(n){case"children":"string"==typeof r?"body"===t||"textarea"===t&&""===r||St(e,r):("number"==typeof r||"bigint"==typeof r)&&"body"!==t&&St(e,""+r);break;case"className":nt(e,"class",r);break;case"tabIndex":nt(e,"tabindex",r);break;case"dir":case"role":case"viewBox":case"width":case"height":nt(e,n,r);break;case"style":Et(e,r,o);break;case"data":if("object"!==t){nt(e,"data",r);break}case"src":case"href":if(""===r&&("a"!==t||"href"!==n)){e.removeAttribute(n);break}if(null==r||"function"==typeof r||"symbol"==typeof r||"boolean"==typeof r){e.removeAttribute(n);break}r=Tt(""+r),e.setAttribute(n,r);break;case"action":case"formAction":if("function"==typeof r){e.setAttribute(n,"javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')");break}if("function"==typeof o&&("formAction"===n?("input"!==t&&Zu(e,t,"name",a.name,a,null),Zu(e,t,"formEncType",a.formEncType,a,null),Zu(e,t,"formMethod",a.formMethod,a,null),Zu(e,t,"formTarget",a.formTarget,a,null)):(Zu(e,t,"encType",a.encType,a,null),Zu(e,t,"method",a.method,a,null),Zu(e,t,"target",a.target,a,null))),null==r||"symbol"==typeof r||"boolean"==typeof r){e.removeAttribute(n);break}r=Tt(""+r),e.setAttribute(n,r);break;case"onClick":null!=r&&(e.onclick=Xu);break;case"onScroll":null!=r&&Bu("scroll",e);break;case"onScrollEnd":null!=r&&Bu("scrollend",e);break;case"dangerouslySetInnerHTML":if(null!=r){if("object"!=typeof r||!("__html"in r))throw Error(i(61));if(null!=(n=r.__html)){if(null!=a.children)throw Error(i(60));e.innerHTML=n}}break;case"multiple":e.multiple=r&&"function"!=typeof r&&"symbol"!=typeof r;break;case"muted":e.muted=r&&"function"!=typeof r&&"symbol"!=typeof r;break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"defaultValue":case"defaultChecked":case"innerHTML":case"ref":case"autoFocus":break;case"xlinkHref":if(null==r||"function"==typeof r||"boolean"==typeof r||"symbol"==typeof r){e.removeAttribute("xlink:href");break}n=Tt(""+r),e.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",n);break;case"contentEditable":case"spellCheck":case"draggable":case"value":case"autoReverse":case"externalResourcesRequired":case"focusable":case"preserveAlpha":null!=r&&"function"!=typeof r&&"symbol"!=typeof r?e.setAttribute(n,""+r):e.removeAttribute(n);break;case"inert":case"allowFullScreen":case"async":case"autoPlay":case"controls":case"default":case"defer":case"disabled":case"disablePictureInPicture":case"disableRemotePlayback":case"formNoValidate":case"hidden":case"loop":case"noModule":case"noValidate":case"open":case"playsInline":case"readOnly":case"required":case"reversed":case"scoped":case"seamless":case"itemScope":r&&"function"!=typeof r&&"symbol"!=typeof r?e.setAttribute(n,""):e.removeAttribute(n);break;case"capture":case"download":!0===r?e.setAttribute(n,""):!1!==r&&null!=r&&"function"!=typeof r&&"symbol"!=typeof r?e.setAttribute(n,r):e.removeAttribute(n);break;case"cols":case"rows":case"size":case"span":null!=r&&"function"!=typeof r&&"symbol"!=typeof r&&!isNaN(r)&&1<=r?e.setAttribute(n,r):e.removeAttribute(n);break;case"rowSpan":case"start":null==r||"function"==typeof r||"symbol"==typeof r||isNaN(r)?e.removeAttribute(n):e.setAttribute(n,r);break;case"popover":Bu("beforetoggle",e),Bu("toggle",e),tt(e,"popover",r);break;case"xlinkActuate":rt(e,"http://www.w3.org/1999/xlink","xlink:actuate",r);break;case"xlinkArcrole":rt(e,"http://www.w3.org/1999/xlink","xlink:arcrole",r);break;case"xlinkRole":rt(e,"http://www.w3.org/1999/xlink","xlink:role",r);break;case"xlinkShow":rt(e,"http://www.w3.org/1999/xlink","xlink:show",r);break;case"xlinkTitle":rt(e,"http://www.w3.org/1999/xlink","xlink:title",r);break;case"xlinkType":rt(e,"http://www.w3.org/1999/xlink","xlink:type",r);break;case"xmlBase":rt(e,"http://www.w3.org/XML/1998/namespace","xml:base",r);break;case"xmlLang":rt(e,"http://www.w3.org/XML/1998/namespace","xml:lang",r);break;case"xmlSpace":rt(e,"http://www.w3.org/XML/1998/namespace","xml:space",r);break;case"is":tt(e,"is",r);break;case"innerText":case"textContent":break;default:(!(2<n.length)||"o"!==n[0]&&"O"!==n[0]||"n"!==n[1]&&"N"!==n[1])&&tt(e,n=At.get(n)||n,r)}}function Ju(e,t,n,r,a,o){switch(n){case"style":Et(e,r,o);break;case"dangerouslySetInnerHTML":if(null!=r){if("object"!=typeof r||!("__html"in r))throw Error(i(61));if(null!=(n=r.__html)){if(null!=a.children)throw Error(i(60));e.innerHTML=n}}break;case"children":"string"==typeof r?St(e,r):("number"==typeof r||"bigint"==typeof r)&&St(e,""+r);break;case"onScroll":null!=r&&Bu("scroll",e);break;case"onScrollEnd":null!=r&&Bu("scrollend",e);break;case"onClick":null!=r&&(e.onclick=Xu);break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"innerHTML":case"ref":case"innerText":case"textContent":break;default:We.hasOwnProperty(n)||("o"!==n[0]||"n"!==n[1]||(a=n.endsWith("Capture"),t=n.slice(2,a?n.length-7:void 0),"function"==typeof(o=null!=(o=e[Ne]||null)?o[n]:null)&&e.removeEventListener(t,o,a),"function"!=typeof r)?n in e?e[n]=r:!0===r?e.setAttribute(n,""):tt(e,n,r):("function"!=typeof o&&null!==o&&(n in e?e[n]=null:e.hasAttribute(n)&&e.removeAttribute(n)),e.addEventListener(t,r,a)))}}function ed(e,t,n){switch(t){case"div":case"span":case"svg":case"path":case"a":case"g":case"p":case"li":break;case"img":Bu("error",e),Bu("load",e);var r,a=!1,o=!1;for(r in n)if(n.hasOwnProperty(r)){var l=n[r];if(null!=l)switch(r){case"src":a=!0;break;case"srcSet":o=!0;break;case"children":case"dangerouslySetInnerHTML":throw Error(i(137,t));default:Zu(e,t,r,l,n,null)}}return o&&Zu(e,t,"srcSet",n.srcSet,n,null),void(a&&Zu(e,t,"src",n.src,n,null));case"input":Bu("invalid",e);var s=r=l=o=null,c=null,u=null;for(a in n)if(n.hasOwnProperty(a)){var d=n[a];if(null!=d)switch(a){case"name":o=d;break;case"type":l=d;break;case"checked":c=d;break;case"defaultChecked":u=d;break;case"value":r=d;break;case"defaultValue":s=d;break;case"children":case"dangerouslySetInnerHTML":if(null!=d)throw Error(i(137,t));break;default:Zu(e,t,a,d,n,null)}}return bt(e,r,s,c,u,l,o,!1),void dt(e);case"select":for(o in Bu("invalid",e),a=l=r=null,n)if(n.hasOwnProperty(o)&&null!=(s=n[o]))switch(o){case"value":r=s;break;case"defaultValue":l=s;break;case"multiple":a=s;default:Zu(e,t,o,s,n,null)}return t=r,n=l,e.multiple=!!a,void(null!=t?vt(e,!!a,t,!1):null!=n&&vt(e,!!a,n,!0));case"textarea":for(l in Bu("invalid",e),r=o=a=null,n)if(n.hasOwnProperty(l)&&null!=(s=n[l]))switch(l){case"value":a=s;break;case"defaultValue":o=s;break;case"children":r=s;break;case"dangerouslySetInnerHTML":if(null!=s)throw Error(i(91));break;default:Zu(e,t,l,s,n,null)}return kt(e,a,o,r),void dt(e);case"option":for(c in n)if(n.hasOwnProperty(c)&&null!=(a=n[c]))if("selected"===c)e.selected=a&&"function"!=typeof a&&"symbol"!=typeof a;else Zu(e,t,c,a,n,null);return;case"dialog":Bu("beforetoggle",e),Bu("toggle",e),Bu("cancel",e),Bu("close",e);break;case"iframe":case"object":Bu("load",e);break;case"video":case"audio":for(a=0;a<Ou.length;a++)Bu(Ou[a],e);break;case"image":Bu("error",e),Bu("load",e);break;case"details":Bu("toggle",e);break;case"embed":case"source":case"link":Bu("error",e),Bu("load",e);case"area":case"base":case"br":case"col":case"hr":case"keygen":case"meta":case"param":case"track":case"wbr":case"menuitem":for(u in n)if(n.hasOwnProperty(u)&&null!=(a=n[u]))switch(u){case"children":case"dangerouslySetInnerHTML":throw Error(i(137,t));default:Zu(e,t,u,a,n,null)}return;default:if(Ct(t)){for(d in n)n.hasOwnProperty(d)&&(void 0!==(a=n[d])&&Ju(e,t,d,a,n,void 0));return}}for(s in n)n.hasOwnProperty(s)&&(null!=(a=n[s])&&Zu(e,t,s,a,n,null))}var td=null,nd=null;function rd(e){return 9===e.nodeType?e:e.ownerDocument}function ad(e){switch(e){case"http://www.w3.org/2000/svg":return 1;case"http://www.w3.org/1998/Math/MathML":return 2;default:return 0}}function od(e,t){if(0===e)switch(t){case"svg":return 1;case"math":return 2;default:return 0}return 1===e&&"foreignObject"===t?0:e}function id(e,t){return"textarea"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"bigint"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var ld=null;var sd="function"==typeof setTimeout?setTimeout:void 0,cd="function"==typeof clearTimeout?clearTimeout:void 0,ud="function"==typeof Promise?Promise:void 0,dd="function"==typeof queueMicrotask?queueMicrotask:void 0!==ud?function(e){return ud.resolve(null).then(e).catch(fd)}:sd;function fd(e){setTimeout(function(){throw e})}function pd(e){return"head"===e}function hd(e,t){var n=t,r=0,a=0;do{var o=n.nextSibling;if(e.removeChild(n),o&&8===o.nodeType)if("/$"===(n=o.data)){if(0<r&&8>r){n=r;var i=e.ownerDocument;if(1&n&&kd(i.documentElement),2&n&&kd(i.body),4&n)for(kd(n=i.head),i=n.firstChild;i;){var l=i.nextSibling,s=i.nodeName;i[Ie]||"SCRIPT"===s||"STYLE"===s||"LINK"===s&&"stylesheet"===i.rel.toLowerCase()||n.removeChild(i),i=l}}if(0===a)return e.removeChild(o),void Lf(t);a--}else"$"===n||"$?"===n||"$!"===n?a++:r=n.charCodeAt(0)-48;else r=0;n=o}while(n);Lf(t)}function md(e){var t=e.firstChild;for(t&&10===t.nodeType&&(t=t.nextSibling);t;){var n=t;switch(t=t.nextSibling,n.nodeName){case"HTML":case"HEAD":case"BODY":md(n),ze(n);continue;case"SCRIPT":case"STYLE":continue;case"LINK":if("stylesheet"===n.rel.toLowerCase())continue}e.removeChild(n)}}function gd(e){return"$!"===e.data||"$?"===e.data&&"complete"===e.ownerDocument.readyState}function bd(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break;if(8===t){if("$"===(t=e.data)||"$!"===t||"$?"===t||"F!"===t||"F"===t)break;if("/$"===t)return null}}return e}var yd=null;function vd(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}function wd(e,t,n){switch(t=rd(n),e){case"html":if(!(e=t.documentElement))throw Error(i(452));return e;case"head":if(!(e=t.head))throw Error(i(453));return e;case"body":if(!(e=t.body))throw Error(i(454));return e;default:throw Error(i(451))}}function kd(e){for(var t=e.attributes;t.length;)e.removeAttributeNode(t[0]);ze(e)}var Sd=new Map,xd=new Set;function _d(e){return"function"==typeof e.getRootNode?e.getRootNode():9===e.nodeType?e:e.ownerDocument}var Ed=R.d;R.d={f:function(){var e=Ed.f(),t=$c();return e||t},r:function(e){var t=Ue(e);null!==t&&5===t.tag&&"form"===t.type?Ni(t):Ed.r(e)},D:function(e){Ed.D(e),Ad("dns-prefetch",e,null)},C:function(e,t){Ed.C(e,t),Ad("preconnect",e,t)},L:function(e,t,n){Ed.L(e,t,n);var r=Cd;if(r&&e&&t){var a='link[rel="preload"][as="'+mt(t)+'"]';"image"===t&&n&&n.imageSrcSet?(a+='[imagesrcset="'+mt(n.imageSrcSet)+'"]',"string"==typeof n.imageSizes&&(a+='[imagesizes="'+mt(n.imageSizes)+'"]')):a+='[href="'+mt(e)+'"]';var o=a;switch(t){case"style":o=Td(e);break;case"script":o=Md(e)}Sd.has(o)||(e=f({rel:"preload",href:"image"===t&&n&&n.imageSrcSet?void 0:e,as:t},n),Sd.set(o,e),null!==r.querySelector(a)||"style"===t&&r.querySelector(jd(o))||"script"===t&&r.querySelector(Nd(o))||(ed(t=r.createElement("link"),"link",e),Ge(t),r.head.appendChild(t)))}},m:function(e,t){Ed.m(e,t);var n=Cd;if(n&&e){var r=t&&"string"==typeof t.as?t.as:"script",a='link[rel="modulepreload"][as="'+mt(r)+'"][href="'+mt(e)+'"]',o=a;switch(r){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":o=Md(e)}if(!Sd.has(o)&&(e=f({rel:"modulepreload",href:e},t),Sd.set(o,e),null===n.querySelector(a))){switch(r){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(n.querySelector(Nd(o)))return}ed(r=n.createElement("link"),"link",e),Ge(r),n.head.appendChild(r)}}},X:function(e,t){Ed.X(e,t);var n=Cd;if(n&&e){var r=He(n).hoistableScripts,a=Md(e),o=r.get(a);o||((o=n.querySelector(Nd(a)))||(e=f({src:e,async:!0},t),(t=Sd.get(a))&&Bd(e,t),Ge(o=n.createElement("script")),ed(o,"link",e),n.head.appendChild(o)),o={type:"script",instance:o,count:1,state:null},r.set(a,o))}},S:function(e,t,n){Ed.S(e,t,n);var r=Cd;if(r&&e){var a=He(r).hoistableStyles,o=Td(e);t=t||"default";var i=a.get(o);if(!i){var l={loading:0,preload:null};if(i=r.querySelector(jd(o)))l.loading=5;else{e=f({rel:"stylesheet",href:e,"data-precedence":t},n),(n=Sd.get(o))&&Dd(e,n);var s=i=r.createElement("link");Ge(s),ed(s,"link",e),s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),s.addEventListener("load",function(){l.loading|=1}),s.addEventListener("error",function(){l.loading|=2}),l.loading|=4,Rd(i,t,r)}i={type:"stylesheet",instance:i,count:1,state:l},a.set(o,i)}}},M:function(e,t){Ed.M(e,t);var n=Cd;if(n&&e){var r=He(n).hoistableScripts,a=Md(e),o=r.get(a);o||((o=n.querySelector(Nd(a)))||(e=f({src:e,async:!0,type:"module"},t),(t=Sd.get(a))&&Bd(e,t),Ge(o=n.createElement("script")),ed(o,"link",e),n.head.appendChild(o)),o={type:"script",instance:o,count:1,state:null},r.set(a,o))}}};var Cd="undefined"==typeof document?null:document;function Ad(e,t,n){var r=Cd;if(r&&"string"==typeof t&&t){var a=mt(t);a='link[rel="'+e+'"][href="'+a+'"]',"string"==typeof n&&(a+='[crossorigin="'+n+'"]'),xd.has(a)||(xd.add(a),e={rel:e,crossOrigin:n,href:t},null===r.querySelector(a)&&(ed(t=r.createElement("link"),"link",e),Ge(t),r.head.appendChild(t)))}}function Ld(e,t,n,r){var a,o,l,s,c=(c=H.current)?_d(c):null;if(!c)throw Error(i(446));switch(e){case"meta":case"title":return null;case"style":return"string"==typeof n.precedence&&"string"==typeof n.href?(t=Td(n.href),(r=(n=He(c).hoistableStyles).get(t))||(r={type:"style",instance:null,count:0,state:null},n.set(t,r)),r):{type:"void",instance:null,count:0,state:null};case"link":if("stylesheet"===n.rel&&"string"==typeof n.href&&"string"==typeof n.precedence){e=Td(n.href);var u=He(c).hoistableStyles,d=u.get(e);if(d||(c=c.ownerDocument||c,d={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},u.set(e,d),(u=c.querySelector(jd(e)))&&!u._p&&(d.instance=u,d.state.loading=5),Sd.has(e)||(n={rel:"preload",as:"style",href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},Sd.set(e,n),u||(a=c,o=e,l=n,s=d.state,a.querySelector('link[rel="preload"][as="style"]['+o+"]")?s.loading=1:(o=a.createElement("link"),s.preload=o,o.addEventListener("load",function(){return s.loading|=1}),o.addEventListener("error",function(){return s.loading|=2}),ed(o,"link",l),Ge(o),a.head.appendChild(o))))),t&&null===r)throw Error(i(528,""));return d}if(t&&null!==r)throw Error(i(529,""));return null;case"script":return t=n.async,"string"==typeof(n=n.src)&&t&&"function"!=typeof t&&"symbol"!=typeof t?(t=Md(n),(r=(n=He(c).hoistableScripts).get(t))||(r={type:"script",instance:null,count:0,state:null},n.set(t,r)),r):{type:"void",instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Td(e){return'href="'+mt(e)+'"'}function jd(e){return'link[rel="stylesheet"]['+e+"]"}function Pd(e){return f({},e,{"data-precedence":e.precedence,precedence:null})}function Md(e){return'[src="'+mt(e)+'"]'}function Nd(e){return"script[async]"+e}function Od(e,t,n){if(t.count++,null===t.instance)switch(t.type){case"style":var r=e.querySelector('style[data-href~="'+mt(n.href)+'"]');if(r)return t.instance=r,Ge(r),r;var a=f({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return Ge(r=(e.ownerDocument||e).createElement("style")),ed(r,"style",a),Rd(r,n.precedence,e),t.instance=r;case"stylesheet":a=Td(n.href);var o=e.querySelector(jd(a));if(o)return t.state.loading|=4,t.instance=o,Ge(o),o;r=Pd(n),(a=Sd.get(a))&&Dd(r,a),Ge(o=(e.ownerDocument||e).createElement("link"));var l=o;return l._p=new Promise(function(e,t){l.onload=e,l.onerror=t}),ed(o,"link",r),t.state.loading|=4,Rd(o,n.precedence,e),t.instance=o;case"script":return o=Md(n.src),(a=e.querySelector(Nd(o)))?(t.instance=a,Ge(a),a):(r=n,(a=Sd.get(o))&&Bd(r=f({},n),a),Ge(a=(e=e.ownerDocument||e).createElement("script")),ed(a,"link",r),e.head.appendChild(a),t.instance=a);case"void":return null;default:throw Error(i(443,t.type))}else"stylesheet"===t.type&&!(4&t.state.loading)&&(r=t.instance,t.state.loading|=4,Rd(r,n.precedence,e));return t.instance}function Rd(e,t,n){for(var r=n.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),a=r.length?r[r.length-1]:null,o=a,i=0;i<r.length;i++){var l=r[i];if(l.dataset.precedence===t)o=l;else if(o!==a)break}o?o.parentNode.insertBefore(e,o.nextSibling):(t=9===n.nodeType?n.head:n).insertBefore(e,t.firstChild)}function Dd(e,t){null==e.crossOrigin&&(e.crossOrigin=t.crossOrigin),null==e.referrerPolicy&&(e.referrerPolicy=t.referrerPolicy),null==e.title&&(e.title=t.title)}function Bd(e,t){null==e.crossOrigin&&(e.crossOrigin=t.crossOrigin),null==e.referrerPolicy&&(e.referrerPolicy=t.referrerPolicy),null==e.integrity&&(e.integrity=t.integrity)}var Fd=null;function Id(e,t,n){if(null===Fd){var r=new Map,a=Fd=new Map;a.set(n,r)}else(r=(a=Fd).get(n))||(r=new Map,a.set(n,r));if(r.has(e))return r;for(r.set(e,null),n=n.getElementsByTagName(e),a=0;a<n.length;a++){var o=n[a];if(!(o[Ie]||o[Me]||"link"===e&&"stylesheet"===o.getAttribute("rel"))&&"http://www.w3.org/2000/svg"!==o.namespaceURI){var i=o.getAttribute(t)||"";i=e+i;var l=r.get(i);l?l.push(o):r.set(i,[o])}}return r}function zd(e,t,n){(e=e.ownerDocument||e).head.insertBefore(n,"title"===t?e.querySelector("head > title"):null)}function $d(e){return!!("stylesheet"!==e.type||3&e.state.loading)}var Ud=null;function qd(){}function Hd(){if(this.count--,0===this.count)if(this.stylesheets)Vd(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}var Gd=null;function Vd(e,t){e.stylesheets=null,null!==e.unsuspend&&(e.count++,Gd=new Map,t.forEach(Wd,e),Gd=null,Hd.call(e))}function Wd(e,t){if(!(4&t.state.loading)){var n=Gd.get(e);if(n)var r=n.get(null);else{n=new Map,Gd.set(e,n);for(var a=e.querySelectorAll("link[data-precedence],style[data-precedence]"),o=0;o<a.length;o++){var i=a[o];"LINK"!==i.nodeName&&"not all"===i.getAttribute("media")||(n.set(i.dataset.precedence,i),r=i)}r&&n.set(null,r)}i=(a=t.instance).getAttribute("data-precedence"),(o=n.get(i)||r)===r&&n.set(null,a),n.set(i,a),this.count++,r=Hd.bind(this),a.addEventListener("load",r),a.addEventListener("error",r),o?o.parentNode.insertBefore(a,o.nextSibling):(e=9===e.nodeType?e.head:e).insertBefore(a,e.firstChild),t.state.loading|=4}}var Qd={$$typeof:k,Provider:null,Consumer:null,_currentValue:D,_currentValue2:D,_threadCount:0};function Kd(e,t,n,r,a,o,i,l){this.tag=1,this.containerInfo=e,this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.next=this.pendingContext=this.context=this.cancelPendingCommit=null,this.callbackPriority=0,this.expirationTimes=_e(-1),this.entangledLanes=this.shellSuspendCounter=this.errorRecoveryDisabledLanes=this.expiredLanes=this.warmLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=_e(0),this.hiddenUpdates=_e(null),this.identifierPrefix=r,this.onUncaughtError=a,this.onCaughtError=o,this.onRecoverableError=i,this.pooledCache=null,this.pooledCacheLanes=0,this.formState=l,this.incompleteTransitions=new Map}function Yd(e,t,n,r,a,o,i,l,s,c,u,d){return e=new Kd(e,t,n,i,l,s,c,d),t=1,!0===o&&(t|=24),o=Dr(3,null,null,t),e.current=o,o.stateNode=e,(t=Na()).refCount++,e.pooledCache=t,t.refCount++,o.memoizedState={element:r,isDehydrated:n,cache:t},no(o),e}function Xd(e){return e?e=Or:Or}function Zd(e,t,n,r,a,o){a=Xd(a),null===r.context?r.context=a:r.pendingContext=a,(r=ao(t)).payload={element:n},null!==(o=void 0===o?null:o)&&(r.callback=o),null!==(n=oo(e,r,t))&&(Dc(n,0,t),io(n,e,t))}function Jd(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function ef(e,t){Jd(e,t),(e=e.alternate)&&Jd(e,t)}function tf(e){if(13===e.tag){var t=Pr(e,67108864);null!==t&&Dc(t,0,67108864),ef(e,67108864)}}var nf=!0;function rf(e,t,n,r){var a=O.T;O.T=null;var o=R.p;try{R.p=2,of(e,t,n,r)}finally{R.p=o,O.T=a}}function af(e,t,n,r){var a=O.T;O.T=null;var o=R.p;try{R.p=8,of(e,t,n,r)}finally{R.p=o,O.T=a}}function of(e,t,n,r){if(nf){var a=lf(r);if(null===a)Uu(e,t,r,sf,n),vf(e,r);else if(function(e,t,n,r,a){switch(t){case"focusin":return ff=wf(ff,e,t,n,r,a),!0;case"dragenter":return pf=wf(pf,e,t,n,r,a),!0;case"mouseover":return hf=wf(hf,e,t,n,r,a),!0;case"pointerover":var o=a.pointerId;return mf.set(o,wf(mf.get(o)||null,e,t,n,r,a)),!0;case"gotpointercapture":return o=a.pointerId,gf.set(o,wf(gf.get(o)||null,e,t,n,r,a)),!0}return!1}(a,e,t,n,r))r.stopPropagation();else if(vf(e,r),4&t&&-1<yf.indexOf(e)){for(;null!==a;){var o=Ue(a);if(null!==o)switch(o.tag){case 3:if((o=o.stateNode).current.memoizedState.isDehydrated){var i=ye(o.pendingLanes);if(0!==i){var l=o;for(l.pendingLanes|=2,l.entangledLanes|=2;i;){var s=1<<31-pe(i);l.entanglements[1]|=s,i&=~s}Su(o),!(6&nc)&&(Sc=te()+500,xu(0,!1))}}break;case 13:null!==(l=Pr(o,2))&&Dc(l,0,2),$c(),ef(o,2)}if(null===(o=lf(r))&&Uu(e,t,r,sf,n),o===a)break;a=o}null!==a&&r.stopPropagation()}else Uu(e,t,r,null,n)}}function lf(e){return cf(e=Pt(e))}var sf=null;function cf(e){if(sf=null,null!==(e=$e(e))){var t=s(e);if(null===t)e=null;else{var n=t.tag;if(13===n){if(null!==(e=c(t)))return e;e=null}else if(3===n){if(t.stateNode.current.memoizedState.isDehydrated)return 3===t.tag?t.stateNode.containerInfo:null;e=null}else t!==e&&(e=null)}}return sf=e,null}function uf(e){switch(e){case"beforetoggle":case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"toggle":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 2;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 8;case"message":switch(ne()){case re:return 2;case ae:return 8;case oe:case ie:return 32;case le:return 268435456;default:return 32}default:return 32}}var df=!1,ff=null,pf=null,hf=null,mf=new Map,gf=new Map,bf=[],yf="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset".split(" ");function vf(e,t){switch(e){case"focusin":case"focusout":ff=null;break;case"dragenter":case"dragleave":pf=null;break;case"mouseover":case"mouseout":hf=null;break;case"pointerover":case"pointerout":mf.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":gf.delete(t.pointerId)}}function wf(e,t,n,r,a,o){return null===e||e.nativeEvent!==o?(e={blockedOn:t,domEventName:n,eventSystemFlags:r,nativeEvent:o,targetContainers:[a]},null!==t&&(null!==(t=Ue(t))&&tf(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,null!==a&&-1===t.indexOf(a)&&t.push(a),e)}function kf(e){var t=$e(e.target);if(null!==t){var n=s(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=c(n)))return e.blockedOn=t,void function(e,t){var n=R.p;try{return R.p=e,t()}finally{R.p=n}}(e.priority,function(){if(13===n.tag){var e=Oc();e=Le(e);var t=Pr(n,e);null!==t&&Dc(t,0,e),ef(n,e)}})}else if(3===t&&n.stateNode.current.memoizedState.isDehydrated)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function Sf(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=lf(e.nativeEvent);if(null!==n)return null!==(t=Ue(n))&&tf(t),e.blockedOn=n,!1;var r=new(n=e.nativeEvent).constructor(n.type,n);jt=r,n.target.dispatchEvent(r),jt=null,t.shift()}return!0}function xf(e,t,n){Sf(e)&&n.delete(t)}function _f(){df=!1,null!==ff&&Sf(ff)&&(ff=null),null!==pf&&Sf(pf)&&(pf=null),null!==hf&&Sf(hf)&&(hf=null),mf.forEach(xf),gf.forEach(xf)}function Ef(e,t){e.blockedOn===t&&(e.blockedOn=null,df||(df=!0,r.unstable_scheduleCallback(r.unstable_NormalPriority,_f)))}var Cf=null;function Af(e){Cf!==e&&(Cf=e,r.unstable_scheduleCallback(r.unstable_NormalPriority,function(){Cf===e&&(Cf=null);for(var t=0;t<e.length;t+=3){var n=e[t],r=e[t+1],a=e[t+2];if("function"!=typeof r){if(null===cf(r||n))continue;break}var o=Ue(n);null!==o&&(e.splice(t,3),t-=3,Pi(o,{pending:!0,data:a,method:n.method,action:r},r,a))}}))}function Lf(e){function t(t){return Ef(t,e)}null!==ff&&Ef(ff,e),null!==pf&&Ef(pf,e),null!==hf&&Ef(hf,e),mf.forEach(t),gf.forEach(t);for(var n=0;n<bf.length;n++){var r=bf[n];r.blockedOn===e&&(r.blockedOn=null)}for(;0<bf.length&&null===(n=bf[0]).blockedOn;)kf(n),null===n.blockedOn&&bf.shift();if(null!=(n=(e.ownerDocument||e).$$reactFormReplay))for(r=0;r<n.length;r+=3){var a=n[r],o=n[r+1],i=a[Ne]||null;if("function"==typeof o)i||Af(n);else if(i){var l=null;if(o&&o.hasAttribute("formAction")){if(a=o,i=o[Ne]||null)l=i.formAction;else if(null!==cf(a))continue}else l=i.action;"function"==typeof l?n[r+1]=l:(n.splice(r,3),r-=3),Af(n)}}}function Tf(e){this._internalRoot=e}function jf(e){this._internalRoot=e}jf.prototype.render=Tf.prototype.render=function(e){var t=this._internalRoot;if(null===t)throw Error(i(409));Zd(t.current,Oc(),e,t,null,null)},jf.prototype.unmount=Tf.prototype.unmount=function(){var e=this._internalRoot;if(null!==e){this._internalRoot=null;var t=e.containerInfo;Zd(e.current,2,null,e,null,null),$c(),t[Oe]=null}},jf.prototype.unstable_scheduleHydration=function(e){if(e){var t=je();e={blockedOn:null,target:e,priority:t};for(var n=0;n<bf.length&&0!==t&&t<bf[n].priority;n++);bf.splice(n,0,e),0===n&&kf(e)}};var Pf=a.version;if("19.1.1"!==Pf)throw Error(i(527,Pf,"19.1.1"));R.findDOMNode=function(e){var t=e._reactInternals;if(void 0===t){if("function"==typeof e.render)throw Error(i(188));throw e=Object.keys(e).join(","),Error(i(268,e))}return e=function(e){var t=e.alternate;if(!t){if(null===(t=s(e)))throw Error(i(188));return t!==e?null:e}for(var n=e,r=t;;){var a=n.return;if(null===a)break;var o=a.alternate;if(null===o){if(null!==(r=a.return)){n=r;continue}break}if(a.child===o.child){for(o=a.child;o;){if(o===n)return u(a),e;if(o===r)return u(a),t;o=o.sibling}throw Error(i(188))}if(n.return!==r.return)n=a,r=o;else{for(var l=!1,c=a.child;c;){if(c===n){l=!0,n=a,r=o;break}if(c===r){l=!0,r=a,n=o;break}c=c.sibling}if(!l){for(c=o.child;c;){if(c===n){l=!0,n=o,r=a;break}if(c===r){l=!0,r=o,n=a;break}c=c.sibling}if(!l)throw Error(i(189))}}if(n.alternate!==r)throw Error(i(190))}if(3!==n.tag)throw Error(i(188));return n.stateNode.current===n?e:t}(t),e=null===(e=null!==e?d(e):null)?null:e.stateNode};var Mf={bundleType:0,version:"19.1.1",rendererPackageName:"react-dom",currentDispatcherRef:O,reconcilerVersion:"19.1.1"};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var Nf=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!Nf.isDisabled&&Nf.supportsFiber)try{ue=Nf.inject(Mf),de=Nf}catch(Rf){}}t.createRoot=function(e,t){if(!l(e))throw Error(i(299));var n=!1,r="",a=yl,o=vl,s=wl;return null!=t&&(!0===t.unstable_strictMode&&(n=!0),void 0!==t.identifierPrefix&&(r=t.identifierPrefix),void 0!==t.onUncaughtError&&(a=t.onUncaughtError),void 0!==t.onCaughtError&&(o=t.onCaughtError),void 0!==t.onRecoverableError&&(s=t.onRecoverableError),void 0!==t.unstable_transitionCallbacks&&t.unstable_transitionCallbacks),t=Yd(e,1,!1,null,0,n,r,a,o,s,0,null),e[Oe]=t.current,zu(e),new Tf(t)},t.hydrateRoot=function(e,t,n){if(!l(e))throw Error(i(299));var r=!1,a="",o=yl,s=vl,c=wl,u=null;return null!=n&&(!0===n.unstable_strictMode&&(r=!0),void 0!==n.identifierPrefix&&(a=n.identifierPrefix),void 0!==n.onUncaughtError&&(o=n.onUncaughtError),void 0!==n.onCaughtError&&(s=n.onCaughtError),void 0!==n.onRecoverableError&&(c=n.onRecoverableError),void 0!==n.unstable_transitionCallbacks&&n.unstable_transitionCallbacks,void 0!==n.formState&&(u=n.formState)),(t=Yd(e,1,!0,t,0,r,a,o,s,c,0,u)).context=Xd(null),n=t.current,(a=ao(r=Le(r=Oc()))).callback=null,oo(n,a,r),n=r,t.current.lanes=n,Ee(t,n),Su(t),e[Oe]=t.current,zu(e),new jf(t)},t.version="19.1.1"},1312:(e,t,n)=>{"use strict";n.d(t,{A:()=>c,T:()=>s});var r=n(6540),a=n(4848);function o(e,t){const n=e.split(/(\{\w+\})/).map((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e});return n.some(e=>(0,r.isValidElement)(e))?n.map((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e).filter(e=>""!==e):n.join("")}var i=n(2654);function l({id:e,message:t}){if(void 0===e&&void 0===t)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[e??t]??t??e}function s({message:e,id:t},n){return o(l({message:e,id:t}),n)}function c({children:e,id:t,values:n}){if(e&&"string"!=typeof e)throw console.warn("Illegal <Translate> children",e),new Error("The Docusaurus <Translate> component only accept simple string values");const r=l({message:e,id:t});return(0,a.jsx)(a.Fragment,{children:o(r,n)})}},1422:(e,t,n)=>{"use strict";n.d(t,{N:()=>m,u:()=>s});var r=n(6540),a=n(205),o=n(3109),i=n(4848);const l="ease-in-out";function s({initialState:e}){const[t,n]=(0,r.useState)(e??!1),a=(0,r.useCallback)(()=>{n(e=>!e)},[]);return{collapsed:t,setCollapsed:n,toggleCollapsed:a}}const c={display:"none",overflow:"hidden",height:"0px"},u={display:"block",overflow:"visible",height:"auto"};function d(e,t){const n=t?c:u;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f({collapsibleRef:e,collapsed:t,animation:n}){const a=(0,r.useRef)(!1);(0,r.useEffect)(()=>{const r=e.current;function i(){const e=r.scrollHeight,t=n?.duration??function(e){if((0,o.O)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(e);return{transition:`height ${t}ms ${n?.easing??l}`,height:`${e}px`}}function s(){const e=i();r.style.transition=e.transition,r.style.height=e.height}if(!a.current)return d(r,t),void(a.current=!0);return r.style.willChange="height",function(){const e=requestAnimationFrame(()=>{t?(s(),requestAnimationFrame(()=>{r.style.height=c.height,r.style.overflow=c.overflow})):(r.style.display="block",requestAnimationFrame(()=>{s()}))});return()=>cancelAnimationFrame(e)}()},[e,t,n])}function p({as:e="div",collapsed:t,children:n,animation:a,onCollapseTransitionEnd:o,className:l}){const s=(0,r.useRef)(null);return f({collapsibleRef:s,collapsed:t,animation:a}),(0,i.jsx)(e,{ref:s,onTransitionEnd:e=>{"height"===e.propertyName&&(d(s.current,t),o?.(t))},className:l,children:n})}function h({collapsed:e,...t}){const[n,o]=(0,r.useState)(!e),[l,s]=(0,r.useState)(e);return(0,a.A)(()=>{e||o(!0)},[e]),(0,a.A)(()=>{n&&s(e)},[n,e]),n?(0,i.jsx)(p,{...t,collapsed:l}):null}function m({lazy:e,...t}){const n=e?h:p;return(0,i.jsx)(n,{...t})}},1463:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});n(6540);var r=n(5260),a=n(4848);function o({locale:e,version:t,tag:n}){const o=e;return(0,a.jsxs)(r.A,{children:[e&&(0,a.jsx)("meta",{name:"docusaurus_locale",content:e}),t&&(0,a.jsx)("meta",{name:"docusaurus_version",content:t}),n&&(0,a.jsx)("meta",{name:"docusaurus_tag",content:n}),o&&(0,a.jsx)("meta",{name:"docsearch:language",content:o}),t&&(0,a.jsx)("meta",{name:"docsearch:version",content:t}),n&&(0,a.jsx)("meta",{name:"docsearch:docusaurus_tag",content:n})]})}},1513:(e,t,n)=>{"use strict";n.d(t,{zR:()=>w,TM:()=>C,yJ:()=>p,sC:()=>L,AO:()=>f});var r=n(8168);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r<a;n+=1,r+=1)e[n]=e[r];e.pop()}const i=function(e,t){void 0===t&&(t="");var n,r=e&&e.split("/")||[],i=t&&t.split("/")||[],l=e&&a(e),s=t&&a(t),c=l||s;if(e&&a(e)?i=r:r.length&&(i.pop(),i=i.concat(r)),!i.length)return"/";if(i.length){var u=i[i.length-1];n="."===u||".."===u||""===u}else n=!1;for(var d=0,f=i.length;f>=0;f--){var p=i[f];"."===p?o(i,f):".."===p?(o(i,f),d++):d&&(o(i,f),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&a(i[0])||i.unshift("");var h=i.join("/");return n&&"/"!==h.substr(-1)&&(h+="/"),h};var l=n(1561);function s(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function f(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function p(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.A)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function h(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter(function(e){return e!==r})}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];t.forEach(function(e){return e.apply(void 0,n)})}}}var m=!("undefined"==typeof window||!window.document||!window.document.createElement);function g(e,t){t(window.confirm(e))}var b="popstate",y="hashchange";function v(){try{return window.history.state||{}}catch(e){return{}}}function w(e){void 0===e&&(e={}),m||(0,l.A)(!1);var t,n=window.history,a=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,o=!(-1===window.navigator.userAgent.indexOf("Trident")),i=e,c=i.forceRefresh,w=void 0!==c&&c,k=i.getUserConfirmation,S=void 0===k?g:k,x=i.keyLength,_=void 0===x?6:x,E=e.basename?d(s(e.basename)):"";function C(e){var t=e||{},n=t.key,r=t.state,a=window.location,o=a.pathname+a.search+a.hash;return E&&(o=u(o,E)),p(o,r,n)}function A(){return Math.random().toString(36).substr(2,_)}var L=h();function T(e){(0,r.A)($,e),$.length=n.length,L.notifyListeners($.location,$.action)}function j(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||N(C(e.state))}function P(){N(C(v()))}var M=!1;function N(e){if(M)M=!1,T();else{L.confirmTransitionTo(e,"POP",S,function(t){t?T({action:"POP",location:e}):function(e){var t=$.location,n=R.indexOf(t.key);-1===n&&(n=0);var r=R.indexOf(e.key);-1===r&&(r=0);var a=n-r;a&&(M=!0,B(a))}(e)})}}var O=C(v()),R=[O.key];function D(e){return E+f(e)}function B(e){n.go(e)}var F=0;function I(e){1===(F+=e)&&1===e?(window.addEventListener(b,j),o&&window.addEventListener(y,P)):0===F&&(window.removeEventListener(b,j),o&&window.removeEventListener(y,P))}var z=!1;var $={length:n.length,action:"POP",location:O,createHref:D,push:function(e,t){var r="PUSH",o=p(e,t,A(),$.location);L.confirmTransitionTo(o,r,S,function(e){if(e){var t=D(o),i=o.key,l=o.state;if(a)if(n.pushState({key:i,state:l},null,t),w)window.location.href=t;else{var s=R.indexOf($.location.key),c=R.slice(0,s+1);c.push(o.key),R=c,T({action:r,location:o})}else window.location.href=t}})},replace:function(e,t){var r="REPLACE",o=p(e,t,A(),$.location);L.confirmTransitionTo(o,r,S,function(e){if(e){var t=D(o),i=o.key,l=o.state;if(a)if(n.replaceState({key:i,state:l},null,t),w)window.location.replace(t);else{var s=R.indexOf($.location.key);-1!==s&&(R[s]=o.key),T({action:r,location:o})}else window.location.replace(t)}})},go:B,goBack:function(){B(-1)},goForward:function(){B(1)},block:function(e){void 0===e&&(e=!1);var t=L.setPrompt(e);return z||(I(1),z=!0),function(){return z&&(z=!1,I(-1)),t()}},listen:function(e){var t=L.appendListener(e);return I(1),function(){I(-1),t()}}};return $}var k="hashchange",S={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+c(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:c,decodePath:s},slash:{encodePath:s,decodePath:s}};function x(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function _(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function E(e){window.location.replace(x(window.location.href)+"#"+e)}function C(e){void 0===e&&(e={}),m||(0,l.A)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),a=n.getUserConfirmation,o=void 0===a?g:a,i=n.hashType,c=void 0===i?"slash":i,b=e.basename?d(s(e.basename)):"",y=S[c],v=y.encodePath,w=y.decodePath;function C(){var e=w(_());return b&&(e=u(e,b)),p(e)}var A=h();function L(e){(0,r.A)(z,e),z.length=t.length,A.notifyListeners(z.location,z.action)}var T=!1,j=null;function P(){var e,t,n=_(),r=v(n);if(n!==r)E(r);else{var a=C(),i=z.location;if(!T&&(t=a,(e=i).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(j===f(a))return;j=null,function(e){if(T)T=!1,L();else{var t="POP";A.confirmTransitionTo(e,t,o,function(n){n?L({action:t,location:e}):function(e){var t=z.location,n=R.lastIndexOf(f(t));-1===n&&(n=0);var r=R.lastIndexOf(f(e));-1===r&&(r=0);var a=n-r;a&&(T=!0,D(a))}(e)})}}(a)}}var M=_(),N=v(M);M!==N&&E(N);var O=C(),R=[f(O)];function D(e){t.go(e)}var B=0;function F(e){1===(B+=e)&&1===e?window.addEventListener(k,P):0===B&&window.removeEventListener(k,P)}var I=!1;var z={length:t.length,action:"POP",location:O,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=x(window.location.href)),n+"#"+v(b+f(e))},push:function(e,t){var n="PUSH",r=p(e,void 0,void 0,z.location);A.confirmTransitionTo(r,n,o,function(e){if(e){var t=f(r),a=v(b+t);if(_()!==a){j=t,function(e){window.location.hash=e}(a);var o=R.lastIndexOf(f(z.location)),i=R.slice(0,o+1);i.push(t),R=i,L({action:n,location:r})}else L()}})},replace:function(e,t){var n="REPLACE",r=p(e,void 0,void 0,z.location);A.confirmTransitionTo(r,n,o,function(e){if(e){var t=f(r),a=v(b+t);_()!==a&&(j=t,E(a));var o=R.indexOf(f(z.location));-1!==o&&(R[o]=t),L({action:n,location:r})}})},go:D,goBack:function(){D(-1)},goForward:function(){D(1)},block:function(e){void 0===e&&(e=!1);var t=A.setPrompt(e);return I||(F(1),I=!0),function(){return I&&(I=!1,F(-1)),t()}},listen:function(e){var t=A.appendListener(e);return F(1),function(){F(-1),t()}}};return z}function A(e,t,n){return Math.min(Math.max(e,t),n)}function L(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,a=t.initialEntries,o=void 0===a?["/"]:a,i=t.initialIndex,l=void 0===i?0:i,s=t.keyLength,c=void 0===s?6:s,u=h();function d(e){(0,r.A)(w,e),w.length=w.entries.length,u.notifyListeners(w.location,w.action)}function m(){return Math.random().toString(36).substr(2,c)}var g=A(l,0,o.length-1),b=o.map(function(e){return p(e,void 0,"string"==typeof e?m():e.key||m())}),y=f;function v(e){var t=A(w.index+e,0,w.entries.length-1),r=w.entries[t];u.confirmTransitionTo(r,"POP",n,function(e){e?d({action:"POP",location:r,index:t}):d()})}var w={length:b.length,action:"POP",location:b[g],index:g,entries:b,createHref:y,push:function(e,t){var r="PUSH",a=p(e,t,m(),w.location);u.confirmTransitionTo(a,r,n,function(e){if(e){var t=w.index+1,n=w.entries.slice(0);n.length>t?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}})},replace:function(e,t){var r="REPLACE",a=p(e,t,m(),w.location);u.confirmTransitionTo(a,r,n,function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))})},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=w.index+e;return t>=0&&t<w.entries.length},block:function(e){return void 0===e&&(e=!1),u.setPrompt(e)},listen:function(e){return u.appendListener(e)}};return w}},1561:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=!0,a="Invariant failed";function o(e,t){if(!e){if(r)throw new Error(a);var n="function"==typeof t?t():t,o=n?"".concat(a,": ").concat(n):a;throw new Error(o)}}},1635:(e,t,n)=>{"use strict";n.r(t),n.d(t,{__addDisposableResource:()=>R,__assign:()=>o,__asyncDelegator:()=>E,__asyncGenerator:()=>_,__asyncValues:()=>C,__await:()=>x,__awaiter:()=>h,__classPrivateFieldGet:()=>M,__classPrivateFieldIn:()=>O,__classPrivateFieldSet:()=>N,__createBinding:()=>g,__decorate:()=>l,__disposeResources:()=>B,__esDecorate:()=>c,__exportStar:()=>b,__extends:()=>a,__generator:()=>m,__importDefault:()=>P,__importStar:()=>j,__makeTemplateObject:()=>A,__metadata:()=>p,__param:()=>s,__propKey:()=>d,__read:()=>v,__rest:()=>i,__rewriteRelativeImportExtension:()=>F,__runInitializers:()=>u,__setFunctionName:()=>f,__spread:()=>w,__spreadArray:()=>S,__spreadArrays:()=>k,__values:()=>y,default:()=>I});var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},r(e,t)};function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var o=function(){return o=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var a in t=arguments[n])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e},o.apply(this,arguments)};function i(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var a=0;for(r=Object.getOwnPropertySymbols(e);a<r.length;a++)t.indexOf(r[a])<0&&Object.prototype.propertyIsEnumerable.call(e,r[a])&&(n[r[a]]=e[r[a]])}return n}function l(e,t,n,r){var a,o=arguments.length,i=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,n,r);else for(var l=e.length-1;l>=0;l--)(a=e[l])&&(i=(o<3?a(i):o>3?a(t,n,i):a(t,n))||i);return o>3&&i&&Object.defineProperty(t,n,i),i}function s(e,t){return function(n,r){t(n,r,e)}}function c(e,t,n,r,a,o){function i(e){if(void 0!==e&&"function"!=typeof e)throw new TypeError("Function expected");return e}for(var l,s=r.kind,c="getter"===s?"get":"setter"===s?"set":"value",u=!t&&e?r.static?e:e.prototype:null,d=t||(u?Object.getOwnPropertyDescriptor(u,r.name):{}),f=!1,p=n.length-1;p>=0;p--){var h={};for(var m in r)h[m]="access"===m?{}:r[m];for(var m in r.access)h.access[m]=r.access[m];h.addInitializer=function(e){if(f)throw new TypeError("Cannot add initializers after decoration has completed");o.push(i(e||null))};var g=(0,n[p])("accessor"===s?{get:d.get,set:d.set}:d[c],h);if("accessor"===s){if(void 0===g)continue;if(null===g||"object"!=typeof g)throw new TypeError("Object expected");(l=i(g.get))&&(d.get=l),(l=i(g.set))&&(d.set=l),(l=i(g.init))&&a.unshift(l)}else(l=i(g))&&("field"===s?a.unshift(l):d[c]=l)}u&&Object.defineProperty(u,r.name,d),f=!0}function u(e,t,n){for(var r=arguments.length>2,a=0;a<t.length;a++)n=r?t[a].call(e,n):t[a].call(e);return r?n:void 0}function d(e){return"symbol"==typeof e?e:"".concat(e)}function f(e,t,n){return"symbol"==typeof t&&(t=t.description?"[".concat(t.description,"]"):""),Object.defineProperty(e,"name",{configurable:!0,value:n?"".concat(n," ",t):t})}function p(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function h(e,t,n,r){return new(n||(n=Promise))(function(a,o){function i(e){try{s(r.next(e))}catch(t){o(t)}}function l(e){try{s(r.throw(e))}catch(t){o(t)}}function s(e){var t;e.done?a(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(i,l)}s((r=r.apply(e,t||[])).next())})}function m(e,t){var n,r,a,o={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return i.next=l(0),i.throw=l(1),i.return=l(2),"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function l(l){return function(s){return function(l){if(n)throw new TypeError("Generator is already executing.");for(;i&&(i=0,l[0]&&(o=0)),o;)try{if(n=1,r&&(a=2&l[0]?r.return:l[0]?r.throw||((a=r.return)&&a.call(r),0):r.next)&&!(a=a.call(r,l[1])).done)return a;switch(r=0,a&&(l=[2&l[0],a.value]),l[0]){case 0:case 1:a=l;break;case 4:return o.label++,{value:l[1],done:!1};case 5:o.label++,r=l[1],l=[0];continue;case 7:l=o.ops.pop(),o.trys.pop();continue;default:if(!(a=o.trys,(a=a.length>0&&a[a.length-1])||6!==l[0]&&2!==l[0])){o=0;continue}if(3===l[0]&&(!a||l[1]>a[0]&&l[1]<a[3])){o.label=l[1];break}if(6===l[0]&&o.label<a[1]){o.label=a[1],a=l;break}if(a&&o.label<a[2]){o.label=a[2],o.ops.push(l);break}a[2]&&o.ops.pop(),o.trys.pop();continue}l=t.call(e,o)}catch(s){l=[6,s],r=0}finally{n=a=0}if(5&l[0])throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}([l,s])}}}var g=Object.create?function(e,t,n,r){void 0===r&&(r=n);var a=Object.getOwnPropertyDescriptor(t,n);a&&!("get"in a?!t.__esModule:a.writable||a.configurable)||(a={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,a)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]};function b(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||g(t,e,n)}function y(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function v(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,a,o=n.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(r=o.next()).done;)i.push(r.value)}catch(l){a={error:l}}finally{try{r&&!r.done&&(n=o.return)&&n.call(o)}finally{if(a)throw a.error}}return i}function w(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(v(arguments[t]));return e}function k(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),a=0;for(t=0;t<n;t++)for(var o=arguments[t],i=0,l=o.length;i<l;i++,a++)r[a]=o[i];return r}function S(e,t,n){if(n||2===arguments.length)for(var r,a=0,o=t.length;a<o;a++)!r&&a in t||(r||(r=Array.prototype.slice.call(t,0,a)),r[a]=t[a]);return e.concat(r||Array.prototype.slice.call(t))}function x(e){return this instanceof x?(this.v=e,this):new x(e)}function _(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r,a=n.apply(e,t||[]),o=[];return r=Object.create(("function"==typeof AsyncIterator?AsyncIterator:Object).prototype),i("next"),i("throw"),i("return",function(e){return function(t){return Promise.resolve(t).then(e,c)}}),r[Symbol.asyncIterator]=function(){return this},r;function i(e,t){a[e]&&(r[e]=function(t){return new Promise(function(n,r){o.push([e,t,n,r])>1||l(e,t)})},t&&(r[e]=t(r[e])))}function l(e,t){try{(n=a[e](t)).value instanceof x?Promise.resolve(n.value.v).then(s,c):u(o[0][2],n)}catch(r){u(o[0][3],r)}var n}function s(e){l("next",e)}function c(e){l("throw",e)}function u(e,t){e(t),o.shift(),o.length&&l(o[0][0],o[0][1])}}function E(e){var t,n;return t={},r("next"),r("throw",function(e){throw e}),r("return"),t[Symbol.iterator]=function(){return this},t;function r(r,a){t[r]=e[r]?function(t){return(n=!n)?{value:x(e[r](t)),done:!1}:a?a(t):t}:a}}function C(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=y(e),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise(function(r,a){(function(e,t,n,r){Promise.resolve(r).then(function(t){e({value:t,done:n})},t)})(r,a,(t=e[n](t)).done,t.value)})}}}function A(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}var L=Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t},T=function(e){return T=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},T(e)};function j(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n=T(e),r=0;r<n.length;r++)"default"!==n[r]&&g(t,e,n[r]);return L(t,e),t}function P(e){return e&&e.__esModule?e:{default:e}}function M(e,t,n,r){if("a"===n&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?r:"a"===n?r.call(e):r?r.value:t.get(e)}function N(e,t,n,r,a){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!a)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!a:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?a.call(e,n):a?a.value=n:t.set(e,n),n}function O(e,t){if(null===t||"object"!=typeof t&&"function"!=typeof t)throw new TypeError("Cannot use 'in' operator on non-object");return"function"==typeof e?t===e:e.has(t)}function R(e,t,n){if(null!=t){if("object"!=typeof t&&"function"!=typeof t)throw new TypeError("Object expected.");var r,a;if(n){if(!Symbol.asyncDispose)throw new TypeError("Symbol.asyncDispose is not defined.");r=t[Symbol.asyncDispose]}if(void 0===r){if(!Symbol.dispose)throw new TypeError("Symbol.dispose is not defined.");r=t[Symbol.dispose],n&&(a=r)}if("function"!=typeof r)throw new TypeError("Object not disposable.");a&&(r=function(){try{a.call(this)}catch(e){return Promise.reject(e)}}),e.stack.push({value:t,dispose:r,async:n})}else n&&e.stack.push({async:!0});return t}var D="function"==typeof SuppressedError?SuppressedError:function(e,t,n){var r=new Error(n);return r.name="SuppressedError",r.error=e,r.suppressed=t,r};function B(e){function t(t){e.error=e.hasError?new D(t,e.error,"An error was suppressed during disposal."):t,e.hasError=!0}var n,r=0;return function a(){for(;n=e.stack.pop();)try{if(!n.async&&1===r)return r=0,e.stack.push(n),Promise.resolve().then(a);if(n.dispose){var o=n.dispose.call(n.value);if(n.async)return r|=2,Promise.resolve(o).then(a,function(e){return t(e),a()})}else r|=1}catch(i){t(i)}if(1===r)return e.hasError?Promise.reject(e.error):Promise.resolve();if(e.hasError)throw e.error}()}function F(e,t){return"string"==typeof e&&/^\.\.?\//.test(e)?e.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i,function(e,n,r,a,o){return n?t?".jsx":".js":!r||a&&o?r+a+"."+o.toLowerCase()+"js":e}):e}const I={__extends:a,__assign:o,__rest:i,__decorate:l,__param:s,__esDecorate:c,__runInitializers:u,__propKey:d,__setFunctionName:f,__metadata:p,__awaiter:h,__generator:m,__createBinding:g,__exportStar:b,__values:y,__read:v,__spread:w,__spreadArrays:k,__spreadArray:S,__await:x,__asyncGenerator:_,__asyncDelegator:E,__asyncValues:C,__makeTemplateObject:A,__importStar:j,__importDefault:P,__classPrivateFieldGet:M,__classPrivateFieldSet:N,__classPrivateFieldIn:O,__addDisposableResource:R,__disposeResources:B,__rewriteRelativeImportExtension:F}},1656:(e,t,n)=>{"use strict";n.d(t,{A:()=>At});var r=n(6540),a=n(4164),o=n(7489),i=n(5500),l=n(6347),s=n(1312),c=n(5062),u=n(4848);const d="__docusaurus_skipToContent_fallback";function f(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function p(){const e=(0,r.useRef)(null),{action:t}=(0,l.W6)(),n=(0,r.useCallback)(e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&f(t)},[]);return(0,c.$)(({location:n})=>{e.current&&!n.hash&&"PUSH"===t&&f(e.current)}),{containerRef:e,onClick:n}}const h=(0,s.T)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function m(e){const t=e.children??h,{containerRef:n,onClick:r}=p();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":h,children:(0,u.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var g=n(7559),b=n(4090);const y={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(m,{className:y.skipToContent})}var w=n(6342),k=n(5041);function S({width:e=21,height:t=21,color:n="currentColor",strokeWidth:r=1.2,className:a,...o}){return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:e,height:t,...o,children:(0,u.jsx)("g",{stroke:n,strokeWidth:r,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const x={closeButton:"closeButton_CVFx"};function _(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,s.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,a.A)("clean-btn close",x.closeButton,e.className),children:(0,u.jsx)(S,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.p)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,a.A)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const A={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function L(){const{announcementBar:e}=(0,w.p)(),{isActive:t,close:n}=(0,k.M)();if(!t)return null;const{backgroundColor:r,textColor:o,isCloseable:i}=e;return(0,u.jsxs)("div",{className:(0,a.A)(g.G.announcementBar.container,A.announcementBar),style:{backgroundColor:r,color:o},role:"banner",children:[i&&(0,u.jsx)("div",{className:A.announcementBarPlaceholder}),(0,u.jsx)(C,{className:A.announcementBarContent}),i&&(0,u.jsx)(_,{onClick:n,className:A.announcementBarClose})]})}var T=n(9876),j=n(3104);var P=n(9532),M=n(5600);const N=r.createContext(null);function O({children:e}){const t=function(){const e=(0,T.M)(),t=(0,M.YL)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,P.ZC)(o);return(0,r.useEffect)(()=>{o&&!i&&a(!0)},[o,i]),(0,r.useEffect)(()=>{o?e.shown||a(!0):a(!1)},[e.shown,o]),(0,r.useMemo)(()=>[n,a],[n])}();return(0,u.jsx)(N.Provider,{value:t,children:e})}function R(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function D(){const e=(0,r.useContext)(N);if(!e)throw new P.dV("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)(()=>n(!1),[n]),o=(0,M.YL)();return(0,r.useMemo)(()=>({shown:t,hide:a,content:R(o)}),[a,o,t])}function B(e){return parseInt(r.version.split(".")[0],10)<19?{inert:e?"":void 0}:{inert:e}}function F({children:e,inert:t}){return(0,u.jsx)("div",{className:(0,a.A)(g.G.layout.navbar.mobileSidebar.panel,"navbar-sidebar__item menu"),...B(t),children:e})}function I({header:e,primaryMenu:t,secondaryMenu:n}){const{shown:r}=D();return(0,u.jsxs)("div",{className:(0,a.A)(g.G.layout.navbar.mobileSidebar.container,"navbar-sidebar"),children:[e,(0,u.jsxs)("div",{className:(0,a.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":r}),children:[(0,u.jsx)(F,{inert:r,children:t}),(0,u.jsx)(F,{inert:!r,children:n})]})]})}var z=n(5293),$=n(2303);function U(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function q(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}function H(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"})})}const G="toggle_vylO",V="toggleButton_gllP",W="toggleIcon_g3eP",Q="systemToggleIcon_QzmC",K="lightToggleIcon_pyhR",Y="darkToggleIcon_wfgR",X="toggleButtonDisabled_aARS";function Z(e){switch(e){case null:return(0,s.T)({message:"system mode",id:"theme.colorToggle.ariaLabel.mode.system",description:"The name for the system color mode"});case"light":return(0,s.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"});case"dark":return(0,s.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"});default:throw new Error(`unexpected color mode ${e}`)}}function J(e){return(0,s.T)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the color mode toggle"},{mode:Z(e)})}function ee(){return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(U,{"aria-hidden":!0,className:(0,a.A)(W,K)}),(0,u.jsx)(q,{"aria-hidden":!0,className:(0,a.A)(W,Y)}),(0,u.jsx)(H,{"aria-hidden":!0,className:(0,a.A)(W,Q)})]})}function te({className:e,buttonClassName:t,respectPrefersColorScheme:n,value:r,onChange:o}){const i=(0,$.A)();return(0,u.jsx)("div",{className:(0,a.A)(G,e),children:(0,u.jsx)("button",{className:(0,a.A)("clean-btn",V,!i&&X,t),type:"button",onClick:()=>o(function(e,t){if(!t)return"dark"===e?"light":"dark";switch(e){case null:return"light";case"light":return"dark";case"dark":return null;default:throw new Error(`unexpected color mode ${e}`)}}(r,n)),disabled:!i,title:Z(r),"aria-label":J(r),children:(0,u.jsx)(ee,{})})})}const ne=r.memo(te),re={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function ae({className:e}){const t=(0,w.p)().navbar.style,{disableSwitch:n,respectPrefersColorScheme:r}=(0,w.p)().colorMode,{colorModeChoice:a,setColorMode:o}=(0,z.G)();return n?null:(0,u.jsx)(ne,{className:e,buttonClassName:"dark"===t?re.darkNavbarColorModeToggle:void 0,respectPrefersColorScheme:r,value:a,onChange:o})}var oe=n(3465);function ie(){return(0,u.jsx)(oe.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function le(){const e=(0,T.M)();return(0,u.jsx)("button",{type:"button","aria-label":(0,s.T)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(S,{color:"var(--ifm-color-emphasis-600)"})})}function se(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(ie,{}),(0,u.jsx)(ae,{className:"margin-right--md"}),(0,u.jsx)(le,{})]})}var ce=n(8774),ue=n(6025),de=n(6654);function fe(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var pe=n(3186);function he({activeBasePath:e,activeBaseRegex:t,to:n,href:r,label:a,html:o,isDropdownLink:i,prependBaseUrlToHref:l,...s}){const c=(0,ue.Ay)(n),d=(0,ue.Ay)(e),f=(0,ue.Ay)(r,{forcePrependBaseUrl:!0}),p=a&&r&&!(0,de.A)(r),h=o?{dangerouslySetInnerHTML:{__html:o}}:{children:(0,u.jsxs)(u.Fragment,{children:[a,p&&(0,u.jsx)(pe.A,{...i&&{width:12,height:12}})]})};return r?(0,u.jsx)(ce.A,{href:l?f:r,...s,...h}):(0,u.jsx)(ce.A,{to:c,isNavLink:!0,...(e||t)&&{isActive:(e,n)=>t?fe(t,n.pathname):n.pathname.startsWith(d)},...s,...h})}function me({className:e,isDropdownItem:t,...n}){return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(he,{className:(0,a.A)("menu__link",e),...n})})}function ge({className:e,isDropdownItem:t=!1,...n}){const r=(0,u.jsx)(he,{className:(0,a.A)(t?"dropdown__link":"navbar__item navbar__link",e),isDropdownLink:t,...n});return t?(0,u.jsx)("li",{children:r}):r}function be({mobile:e=!1,position:t,...n}){const r=e?me:ge;return(0,u.jsx)(r,{...n,activeClassName:n.activeClassName??(e?"menu__link--active":"navbar__link--active")})}var ye=n(1422),ve=n(9169),we=n(4586);const ke="dropdownNavbarItemMobile_J0Sd";function Se(e,t){return e.some(e=>function(e,t){return!!(0,ve.ys)(e.to,t)||!!fe(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t))}function xe({collapsed:e,onClick:t}){return(0,u.jsx)("button",{"aria-label":e?(0,s.T)({id:"theme.navbar.mobileDropdown.collapseButton.expandAriaLabel",message:"Expand the dropdown",description:"The ARIA label of the button to expand the mobile dropdown navbar item"}):(0,s.T)({id:"theme.navbar.mobileDropdown.collapseButton.collapseAriaLabel",message:"Collapse the dropdown",description:"The ARIA label of the button to collapse the mobile dropdown navbar item"}),"aria-expanded":!e,type:"button",className:"clean-btn menu__caret",onClick:t})}function _e({items:e,className:t,position:n,onClick:o,...i}){const s=function(){const{siteConfig:{baseUrl:e}}=(0,we.A)(),{pathname:t}=(0,l.zy)();return t.replace(e,"/")}(),c=(0,ve.ys)(i.to,s),d=Se(e,s),{collapsed:f,toggleCollapsed:p}=function({active:e}){const{collapsed:t,toggleCollapsed:n,setCollapsed:a}=(0,ye.u)({initialState:()=>!e});return(0,r.useEffect)(()=>{e&&a(!1)},[e,a]),{collapsed:t,toggleCollapsed:n}}({active:c||d}),h=i.to?void 0:"#";return(0,u.jsxs)("li",{className:(0,a.A)("menu__list-item",{"menu__list-item--collapsed":f}),children:[(0,u.jsxs)("div",{className:(0,a.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":c}),children:[(0,u.jsx)(he,{role:"button",className:(0,a.A)(ke,"menu__link menu__link--sublist",t),href:h,...i,onClick:e=>{"#"===h&&e.preventDefault(),p()},children:i.children??i.label}),(0,u.jsx)(xe,{collapsed:f,onClick:e=>{e.preventDefault(),p()}})]}),(0,u.jsx)(ye.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:f,children:e.map((e,t)=>(0,r.createElement)(Ie,{mobile:!0,isDropdownItem:!0,onClick:o,activeClassName:"menu__link--active",...e,key:t}))})]})}function Ee({items:e,position:t,className:n,onClick:o,...i}){const l=(0,r.useRef)(null),[s,c]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{const e=e=>{l.current&&!l.current.contains(e.target)&&c(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}},[l]),(0,u.jsxs)("div",{ref:l,className:(0,a.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===t,"dropdown--show":s}),children:[(0,u.jsx)(he,{"aria-haspopup":"true","aria-expanded":s,role:"button",href:i.to?void 0:"#",className:(0,a.A)("navbar__link",n),...i,onClick:i.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),c(!s))},children:i.children??i.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:e.map((e,t)=>(0,r.createElement)(Ie,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t}))})]})}function Ce({mobile:e=!1,...t}){const n=e?_e:Ee;return(0,u.jsx)(n,{...t})}var Ae=n(2131);function Le({width:e=20,height:t=20,...n}){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:e,height:t,"aria-hidden":!0,...n,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const Te="iconLanguage_nlXk";var je=n(418);const Pe={navbarSearchContainer:"navbarSearchContainer_Bca1"};function Me({children:e,className:t}){return(0,u.jsx)("div",{className:(0,a.A)(t,Pe.navbarSearchContainer),children:e})}var Ne=n(4070),Oe=n(6972);var Re=n(3886);function De({docsPluginId:e,configs:t}){return function(e,t){if(t){const n=new Map(e.map(e=>[e.name,e])),r=(t,r)=>{const a=n.get(t);if(!a)throw new Error(`No docs version exist for name '${t}', please verify your 'docsVersionDropdown' navbar item versions config.\nAvailable version names:\n- ${e.map(e=>`${e.name}`).join("\n- ")}`);return{version:a,label:r?.label??a.label}};return Array.isArray(t)?t.map(e=>r(e,void 0)):Object.entries(t).map(([e,t])=>r(e,t))}return e.map(e=>({version:e,label:e.label}))}((0,Ne.jh)(e),t)}function Be(e,t){return t.alternateDocVersions[e.name]??function(e){return e.docs.find(t=>t.id===e.mainDocId)}(e)}const Fe={default:be,localeDropdown:function({mobile:e,dropdownItemsBefore:t,dropdownItemsAfter:n,queryString:r="",...a}){const{i18n:{currentLocale:o,locales:i,localeConfigs:c}}=(0,we.A)(),d=(0,Ae.o)(),{search:f,hash:p}=(0,l.zy)(),h=[...t,...i.map(t=>{const n=`${`pathname://${d.createUrl({locale:t,fullyQualified:!1})}`}${f}${p}${r}`;return{label:c[t].label,lang:c[t].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:t===o?e?"menu__link--active":"dropdown__link--active":""}}),...n],m=e?(0,s.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):c[o].label;return(0,u.jsx)(Ce,{...a,mobile:e,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(Le,{className:Te}),m]}),items:h})},search:function({mobile:e,className:t}){return e?null:(0,u.jsx)(Me,{className:t,children:(0,u.jsx)(je.A,{})})},dropdown:Ce,html:function({value:e,className:t,mobile:n=!1,isDropdownItem:r=!1}){const o=r?"li":"div";return(0,u.jsx)(o,{className:(0,a.A)({navbar__item:!n&&!r,"menu__list-item":n},t),dangerouslySetInnerHTML:{__html:e}})},doc:function({docId:e,label:t,docsPluginId:n,...r}){const{activeDoc:a}=(0,Ne.zK)(n),o=(0,Oe.QB)(e,n),i=a?.path===o?.path;return null===o||o.unlisted&&!i?null:(0,u.jsx)(be,{exact:!0,...r,isActive:()=>i||!!a?.sidebar&&a.sidebar===o.sidebar,label:t??o.id,to:o.path})},docSidebar:function({sidebarId:e,label:t,docsPluginId:n,...r}){const{activeDoc:a}=(0,Ne.zK)(n),o=(0,Oe.fW)(e,n).link;if(!o)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${e}" doesn't have anything to be linked to.`);return(0,u.jsx)(be,{exact:!0,...r,isActive:()=>a?.sidebar===e,label:t??o.label,to:o.path})},docsVersion:function({label:e,to:t,docsPluginId:n,...r}){const a=(0,Oe.Vd)(n)[0],o=e??a.label,i=t??(e=>e.docs.find(t=>t.id===e.mainDocId))(a).path;return(0,u.jsx)(be,{...r,label:o,to:i})},docsVersionDropdown:function({mobile:e,docsPluginId:t,dropdownActiveClassDisabled:n,dropdownItemsBefore:r,dropdownItemsAfter:a,versions:o,...i}){const{search:c,hash:d}=(0,l.zy)(),f=(0,Ne.zK)(t),{savePreferredVersionName:p}=(0,Re.g1)(t),h=De({docsPluginId:t,configs:o}),m=function({docsPluginId:e,versionItems:t}){return(0,Oe.Vd)(e).map(e=>t.find(t=>t.version===e)).filter(e=>void 0!==e)[0]??t[0]}({docsPluginId:t,versionItems:h}),g=[...r,...h.map(function({version:e,label:t}){return{label:t,to:`${Be(e,f).path}${c}${d}`,isActive:()=>e===f.activeVersion,onClick:()=>p(e.name)}}),...a],b=e&&g.length>1?(0,s.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):m.label,y=e&&g.length>1?void 0:Be(m.version,f).path;return g.length<=1?(0,u.jsx)(be,{...i,mobile:e,label:b,to:y,isActive:n?()=>!1:void 0}):(0,u.jsx)(Ce,{...i,mobile:e,label:b,to:y,items:g,isActive:n?()=>!1:void 0})}};function Ie({type:e,...t}){const n=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(e,t),r=Fe[n];if(!r)throw new Error(`No NavbarItem component found for type "${e}".`);return(0,u.jsx)(r,{...t})}function ze(){const e=(0,T.M)(),t=(0,w.p)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map((t,n)=>(0,r.createElement)(Ie,{mobile:!0,...t,onClick:()=>e.toggle(),key:n}))})}function $e(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(s.A,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Ue(){const e=0===(0,w.p)().navbar.items.length,t=D();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)($e,{onClick:()=>t.hide()}),t.content]})}function qe(){const e=(0,T.M)();return function(e=!0){(0,r.useEffect)(()=>(document.body.style.overflow=e?"hidden":"visible",()=>{document.body.style.overflow="visible"}),[e])}(e.shown),e.shouldRender?(0,u.jsx)(I,{header:(0,u.jsx)(se,{}),primaryMenu:(0,u.jsx)(ze,{}),secondaryMenu:(0,u.jsx)(Ue,{})}):null}const He={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Ge(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,a.A)("navbar-sidebar__backdrop",e.className)})}function Ve({children:e}){const{navbar:{hideOnScroll:t,style:n}}=(0,w.p)(),o=(0,T.M)(),{navbarRef:i,isNavbarVisible:l}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)(e=>{null!==e&&(o.current=e.getBoundingClientRect().height)},[]);return(0,j.Mq)(({scrollY:t},r)=>{if(!e)return;if(t<o.current)return void n(!0);if(a.current)return void(a.current=!1);const i=r?.scrollY,l=document.documentElement.scrollHeight-o.current,s=window.innerHeight;i&&t>=i?n(!1):t+s<l&&n(!0)}),(0,c.$)(t=>{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)}),{navbarRef:i,isNavbarVisible:t}}(t);return(0,u.jsxs)("nav",{ref:i,"aria-label":(0,s.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.A)(g.G.layout.navbar.container,"navbar","navbar--fixed-top",t&&[He.navbarHideable,!l&&He.navbarHidden],{"navbar--dark":"dark"===n,"navbar--primary":"primary"===n,"navbar-sidebar--show":o.shown}),children:[e,(0,u.jsx)(Ge,{onClick:o.toggle}),(0,u.jsx)(qe,{})]})}var We=n(440);const Qe={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};function Ke(e){return(0,u.jsx)("button",{type:"button",...e,children:(0,u.jsx)(s.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function Ye({error:e}){const t=(0,We.rA)(e).map(e=>e.message).join("\n\nCause:\n");return(0,u.jsx)("p",{className:Qe.errorBoundaryError,children:t})}class Xe extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const Ze="right";function Je({width:e=30,height:t=30,className:n,...r}){return(0,u.jsx)("svg",{className:n,width:e,height:t,viewBox:"0 0 30 30","aria-hidden":"true",...r,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function et(){const{toggle:e,shown:t}=(0,T.M)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,s.T)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(Je,{})})}const tt={colorModeToggle:"colorModeToggle_DEke"};function nt({items:e}){return(0,u.jsx)(u.Fragment,{children:e.map((e,t)=>(0,u.jsx)(Xe,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(Ie,{...e})},t))})}function rt({left:e,right:t}){return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:(0,a.A)(g.G.layout.navbar.containerLeft,"navbar__items"),children:e}),(0,u.jsx)("div",{className:(0,a.A)(g.G.layout.navbar.containerRight,"navbar__items navbar__items--right"),children:t})]})}function at(){const e=(0,T.M)(),t=(0,w.p)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??Ze)}return[e.filter(t),e.filter(e=>!t(e))]}(t),a=t.find(e=>"search"===e.type);return(0,u.jsx)(rt,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(et,{}),(0,u.jsx)(ie,{}),(0,u.jsx)(nt,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(nt,{items:r}),(0,u.jsx)(ae,{className:tt.colorModeToggle}),!a&&(0,u.jsx)(Me,{children:(0,u.jsx)(je.A,{})})]})})}function ot(){return(0,u.jsx)(Ve,{children:(0,u.jsx)(at,{})})}function it({item:e}){const{to:t,href:n,label:r,prependBaseUrlToHref:o,className:i,...l}=e,s=(0,ue.Ay)(t),c=(0,ue.Ay)(n,{forcePrependBaseUrl:!0});return(0,u.jsxs)(ce.A,{className:(0,a.A)("footer__link-item",i),...n?{href:o?c:n}:{to:s},...l,children:[r,n&&!(0,de.A)(n)&&(0,u.jsx)(pe.A,{})]})}function lt({item:e}){return e.html?(0,u.jsx)("li",{className:(0,a.A)("footer__item",e.className),dangerouslySetInnerHTML:{__html:e.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(it,{item:e})},e.href??e.to)}function st({column:e}){return(0,u.jsxs)("div",{className:(0,a.A)(g.G.layout.footer.column,"col footer__col",e.className),children:[(0,u.jsx)("div",{className:"footer__title",children:e.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:e.items.map((e,t)=>(0,u.jsx)(lt,{item:e},t))})]})}function ct({columns:e}){return(0,u.jsx)("div",{className:"row footer__links",children:e.map((e,t)=>(0,u.jsx)(st,{column:e},t))})}function ut(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function dt({item:e}){return e.html?(0,u.jsx)("span",{className:(0,a.A)("footer__link-item",e.className),dangerouslySetInnerHTML:{__html:e.html}}):(0,u.jsx)(it,{item:e})}function ft({links:e}){return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:e.map((t,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(dt,{item:t}),e.length!==n+1&&(0,u.jsx)(ut,{})]},n))})})}function pt({links:e}){return function(e){return"title"in e[0]}(e)?(0,u.jsx)(ct,{columns:e}):(0,u.jsx)(ft,{links:e})}var ht=n(1122);const mt="footerLogoLink_BH7S";function gt({logo:e}){const{withBaseUrl:t}=(0,ue.hH)(),n={light:t(e.src),dark:t(e.srcDark??e.src)};return(0,u.jsx)(ht.A,{className:(0,a.A)("footer__logo",e.className),alt:e.alt,sources:n,width:e.width,height:e.height,style:e.style})}function bt({logo:e}){return e.href?(0,u.jsx)(ce.A,{href:e.href,className:mt,target:e.target,children:(0,u.jsx)(gt,{logo:e})}):(0,u.jsx)(gt,{logo:e})}function yt({copyright:e}){return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:e}})}function vt({style:e,links:t,logo:n,copyright:r}){return(0,u.jsx)("footer",{className:(0,a.A)(g.G.layout.footer.container,"footer",{"footer--dark":"dark"===e}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[t,(n||r)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[n&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:n}),r]})]})})}function wt(){const{footer:e}=(0,w.p)();if(!e)return null;const{copyright:t,links:n,logo:r,style:a}=e;return(0,u.jsx)(vt,{style:a,links:n&&n.length>0&&(0,u.jsx)(pt,{links:n}),logo:r&&(0,u.jsx)(bt,{logo:r}),copyright:t&&(0,u.jsx)(yt,{copyright:t})})}const kt=r.memo(wt),St=(0,P.fM)([z.a,k.o,j.Tv,Re.VQ,i.Jx,function({children:e}){return(0,u.jsx)(M.y_,{children:(0,u.jsx)(T.e,{children:(0,u.jsx)(O,{children:e})})})}]);function xt({children:e}){return(0,u.jsx)(St,{children:e})}var _t=n(1107);function Et({error:e,tryAgain:t}){return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(_t.A,{as:"h1",className:"hero__title",children:(0,u.jsx)(s.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(Ke,{onClick:t,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(Ye,{error:e})})]})})})}const Ct={mainWrapper:"mainWrapper_z2l0"};function At(e){const{children:t,noFooter:n,wrapperClassName:r,title:l,description:s}=e;return(0,b.J)(),(0,u.jsxs)(xt,{children:[(0,u.jsx)(i.be,{title:l,description:s}),(0,u.jsx)(v,{}),(0,u.jsx)(L,{}),(0,u.jsx)(ot,{}),(0,u.jsx)("div",{id:d,className:(0,a.A)(g.G.layout.main.container,g.G.wrapper.main,Ct.mainWrapper,r),children:(0,u.jsx)(o.A,{fallback:e=>(0,u.jsx)(Et,{...e}),children:t})}),!n&&(0,u.jsx)(kt,{})]})}},1682:(e,t,n)=>{"use strict";function r(e){return Array.from(new Set(e))}function a(e,t){const n={};let r=0;for(const a of e){const e=t(a,r);n[e]??=[],n[e].push(a),r+=1}return n}n.d(t,{$z:()=>a,sb:()=>r})},1765:(e,t,n)=>{"use strict";n.d(t,{My:()=>A,f4:()=>ne});var r,a,o,i,l,s,c,u=n(6540),d=n(4164),f=Object.create,p=Object.defineProperty,h=Object.defineProperties,m=Object.getOwnPropertyDescriptor,g=Object.getOwnPropertyDescriptors,b=Object.getOwnPropertyNames,y=Object.getOwnPropertySymbols,v=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty,k=Object.prototype.propertyIsEnumerable,S=(e,t,n)=>t in e?p(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,x=(e,t)=>{for(var n in t||(t={}))w.call(t,n)&&S(e,n,t[n]);if(y)for(var n of y(t))k.call(t,n)&&S(e,n,t[n]);return e},_=(e,t)=>h(e,g(t)),E=(e,t)=>{var n={};for(var r in e)w.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&y)for(var r of y(e))t.indexOf(r)<0&&k.call(e,r)&&(n[r]=e[r]);return n},C=(r={"../../node_modules/.pnpm/prismjs@1.29.0_patch_hash=vrxx3pzkik6jpmgpayxfjunetu/node_modules/prismjs/prism.js"(e,t){var n=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var a,o;switch(n=n||{},r.util.type(t)){case"Object":if(o=r.util.objId(t),n[o])return n[o];for(var i in a={},n[o]=a,t)t.hasOwnProperty(i)&&(a[i]=e(t[i],n));return a;case"Array":return o=r.util.objId(t),n[o]?n[o]:(a=[],n[o]=a,t.forEach(function(t,r){a[r]=e(t,n)}),a);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var r="no-"+t;e;){var a=e.classList;if(a.contains(t))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=r.util.clone(r.languages[e]);for(var a in t)n[a]=t[a];return n},insertBefore:function(e,t,n,a){var o=(a=a||r.languages)[e],i={};for(var l in o)if(o.hasOwnProperty(l)){if(l==t)for(var s in n)n.hasOwnProperty(s)&&(i[s]=n[s]);n.hasOwnProperty(l)||(i[l]=o[l])}var c=a[e];return a[e]=i,r.languages.DFS(r.languages,function(t,n){n===c&&t!=e&&(this[t]=i)}),i},DFS:function e(t,n,a,o){o=o||{};var i=r.util.objId;for(var l in t)if(t.hasOwnProperty(l)){n.call(t,l,t[l],a||l);var s=t[l],c=r.util.type(s);"Object"!==c||o[i(s)]?"Array"!==c||o[i(s)]||(o[i(s)]=!0,e(s,n,l,o)):(o[i(s)]=!0,e(s,n,null,o))}}},plugins:{},highlight:function(e,t,n){var o={code:e,grammar:t,language:n};if(r.hooks.run("before-tokenize",o),!o.grammar)throw new Error('The language "'+o.language+'" has no grammar.');return o.tokens=r.tokenize(o.code,o.grammar),r.hooks.run("after-tokenize",o),a.stringify(r.util.encode(o.tokens),o.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var a=new l;return s(a,a.head,e),i(e,a,t,a.head,0),function(e){for(var t=[],n=e.head.next;n!==e.tail;)t.push(n.value),n=n.next;return t}(a)},hooks:{all:{},add:function(e,t){var n=r.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=r.hooks.all[e];if(n&&n.length)for(var a,o=0;a=n[o++];)a(t)}},Token:a};function a(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function o(e,t,n,r){e.lastIndex=t;var a=e.exec(n);if(a&&r&&a[1]){var o=a[1].length;a.index+=o,a[0]=a[0].slice(o)}return a}function i(e,t,n,l,u,d){for(var f in n)if(n.hasOwnProperty(f)&&n[f]){var p=n[f];p=Array.isArray(p)?p:[p];for(var h=0;h<p.length;++h){if(d&&d.cause==f+","+h)return;var m=p[h],g=m.inside,b=!!m.lookbehind,y=!!m.greedy,v=m.alias;if(y&&!m.pattern.global){var w=m.pattern.toString().match(/[imsuy]*$/)[0];m.pattern=RegExp(m.pattern.source,w+"g")}for(var k=m.pattern||m,S=l.next,x=u;S!==t.tail&&!(d&&x>=d.reach);x+=S.value.length,S=S.next){var _=S.value;if(t.length>e.length)return;if(!(_ instanceof a)){var E,C=1;if(y){if(!(E=o(k,x,e,b))||E.index>=e.length)break;var A=E.index,L=E.index+E[0].length,T=x;for(T+=S.value.length;A>=T;)T+=(S=S.next).value.length;if(x=T-=S.value.length,S.value instanceof a)continue;for(var j=S;j!==t.tail&&(T<L||"string"==typeof j.value);j=j.next)C++,T+=j.value.length;C--,_=e.slice(x,T),E.index-=x}else if(!(E=o(k,0,_,b)))continue;A=E.index;var P=E[0],M=_.slice(0,A),N=_.slice(A+P.length),O=x+_.length;d&&O>d.reach&&(d.reach=O);var R=S.prev;if(M&&(R=s(t,R,M),x+=M.length),c(t,R,C),S=s(t,R,new a(f,g?r.tokenize(P,g):P,v,P)),N&&s(t,S,N),C>1){var D={cause:f+","+h,reach:O};i(e,t,n,S.prev,x,D),d&&D.reach>d.reach&&(d.reach=D.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function s(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function c(e,t,n){for(var r=t.next,a=0;a<n&&r!==e.tail;a++)r=r.next;t.next=r,r.prev=t,e.length-=a}return a.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var a="";return t.forEach(function(t){a+=e(t,n)}),a}var o={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},i=t.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(o.classes,i):o.classes.push(i)),r.hooks.run("wrap",o);var l="";for(var s in o.attributes)l+=" "+s+'="'+(o.attributes[s]||"").replace(/"/g,""")+'"';return"<"+o.tag+' class="'+o.classes.join(" ")+'"'+l+">"+o.content+"</"+o.tag+">"},r}();t.exports=n,n.default=n}},function(){return a||(0,r[b(r)[0]])((a={exports:{}}).exports,a),a.exports}),A=((e,t,n)=>(n=null!=e?f(v(e)):{},((e,t,n,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let a of b(t))w.call(e,a)||a===n||p(e,a,{get:()=>t[a],enumerable:!(r=m(t,a))||r.enumerable});return e})(!t&&e&&e.__esModule?n:p(n,"default",{value:e,enumerable:!0}),e)))(C());A.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},A.languages.markup.tag.inside["attr-value"].inside.entity=A.languages.markup.entity,A.languages.markup.doctype.inside["internal-subset"].inside=A.languages.markup,A.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Object.defineProperty(A.languages.markup.tag,"addInlined",{value:function(e,t){var n;(t=((n=((n={})["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:A.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i,{"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}}))["language-"+t]={pattern:/[\s\S]+/,inside:A.languages[t]},{}))[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,function(){return e}),"i"),lookbehind:!0,greedy:!0,inside:n},A.languages.insertBefore("markup","cdata",t)}}),Object.defineProperty(A.languages.markup.tag,"addAttribute",{value:function(e,t){A.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:A.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),A.languages.html=A.languages.markup,A.languages.mathml=A.languages.markup,A.languages.svg=A.languages.markup,A.languages.xml=A.languages.extend("markup",{}),A.languages.ssml=A.languages.xml,A.languages.atom=A.languages.xml,A.languages.rss=A.languages.xml,o=A,i={pattern:/\\[\\(){}[\]^$+*?|.]/,alias:"escape"},s="(?:[^\\\\-]|"+(l=/\\(?:x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|0[0-7]{0,2}|[123][0-7]{2}|c[a-zA-Z]|.)/).source+")",s=RegExp(s+"-"+s),c={pattern:/(<|')[^<>']+(?=[>']$)/,lookbehind:!0,alias:"variable"},o.languages.regex={"char-class":{pattern:/((?:^|[^\\])(?:\\\\)*)\[(?:[^\\\]]|\\[\s\S])*\]/,lookbehind:!0,inside:{"char-class-negation":{pattern:/(^\[)\^/,lookbehind:!0,alias:"operator"},"char-class-punctuation":{pattern:/^\[|\]$/,alias:"punctuation"},range:{pattern:s,inside:{escape:l,"range-punctuation":{pattern:/-/,alias:"operator"}}},"special-escape":i,"char-set":{pattern:/\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},escape:l}},"special-escape":i,"char-set":{pattern:/\.|\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},backreference:[{pattern:/\\(?![123][0-7]{2})[1-9]/,alias:"keyword"},{pattern:/\\k<[^<>']+>/,alias:"keyword",inside:{"group-name":c}}],anchor:{pattern:/[$^]|\\[ABbGZz]/,alias:"function"},escape:l,group:[{pattern:/\((?:\?(?:<[^<>']+>|'[^<>']+'|[>:]|<?[=!]|[idmnsuxU]+(?:-[idmnsuxU]+)?:?))?/,alias:"punctuation",inside:{"group-name":c}},{pattern:/\)/,alias:"punctuation"}],quantifier:{pattern:/(?:[+*?]|\{\d+(?:,\d*)?\})[?+]?/,alias:"number"},alternation:{pattern:/\|/,alias:"keyword"}},A.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},A.languages.javascript=A.languages.extend("clike",{"class-name":[A.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),A.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,A.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:A.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:A.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:A.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:A.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:A.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),A.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:A.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),A.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),A.languages.markup&&(A.languages.markup.tag.addInlined("script","javascript"),A.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),A.languages.js=A.languages.javascript,A.languages.actionscript=A.languages.extend("javascript",{keyword:/\b(?:as|break|case|catch|class|const|default|delete|do|dynamic|each|else|extends|final|finally|for|function|get|if|implements|import|in|include|instanceof|interface|internal|is|namespace|native|new|null|override|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|use|var|void|while|with)\b/,operator:/\+\+|--|(?:[+\-*\/%^]|&&?|\|\|?|<<?|>>?>?|[!=]=?)=?|[~?@]/}),A.languages.actionscript["class-name"].alias="function",delete A.languages.actionscript.parameter,delete A.languages.actionscript["literal-property"],A.languages.markup&&A.languages.insertBefore("actionscript","string",{xml:{pattern:/(^|[^.])<\/?\w+(?:\s+[^\s>\/=]+=("|')(?:\\[\s\S]|(?!\2)[^\\])*\2)*\s*\/?>/,lookbehind:!0,inside:A.languages.markup}}),function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(A),function(e){var t=e.languages.javadoclike={parameter:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*@(?:arg|arguments|param)\s+)\w+/m,lookbehind:!0},keyword:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*|\{)@[a-z][a-zA-Z-]+\b/m,lookbehind:!0},punctuation:/[{}]/};Object.defineProperty(t,"addSupport",{value:function(t,n){(t="string"==typeof t?[t]:t).forEach(function(t){var r=function(e){e.inside||(e.inside={}),e.inside.rest=n},a="doc-comment";if(o=e.languages[t]){var o,i=o[a];if((i=i||(o=e.languages.insertBefore(t,"comment",{"doc-comment":{pattern:/(^|[^\\])\/\*\*[^/][\s\S]*?(?:\*\/|$)/,lookbehind:!0,alias:"comment"}}))[a])instanceof RegExp&&(i=o[a]={pattern:i}),Array.isArray(i))for(var l=0,s=i.length;l<s;l++)i[l]instanceof RegExp&&(i[l]={pattern:i[l]}),r(i[l]);else r(i)}})}}),t.addSupport(["java","javascript","php"],t)}(A),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;(t=(e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css,e.languages.markup))&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(A),function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,n=(t=(e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+t.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[t,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}}),{pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0}),{pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0});e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|RebeccaPurple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,number:n})}(A),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source}),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,function(){return r}).replace(/<<value>>/g,function(){return e});return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,function(){return r})),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,function(){return r}).replace(/<<key>>/g,function(){return"(?:"+a+"|"+o+")"})),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(A),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,function(){return t}),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,function(){return r}),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source,i=(e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach(function(t){["url","bold","italic","strike","code-snippet"].forEach(function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])})}),e.hooks.add("after-tokenize",function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n<r;n++){var a,o=t[n];"code"!==o.type?e(o.content):(a=o.content[1],o=o.content[3],a&&o&&"code-language"===a.type&&"code-block"===o.type&&"string"==typeof a.content&&(a=a.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),a="language-"+(a=(/[a-z][\w-]*/i.exec(a)||[""])[0].toLowerCase()),o.alias?"string"==typeof o.alias?o.alias=[o.alias,a]:o.alias.push(a):o.alias=[a]))}}(e.tokens)}),e.hooks.add("wrap",function(t){if("code-block"===t.type){for(var n="",r=0,a=t.classes.length;r<a;r++){var o=t.classes[r];if(o=/language-(.+)/.exec(o)){n=o[1];break}}var c,u=e.languages[n];u?t.content=e.highlight(t.content.replace(i,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,function(e,t){var n;return"#"===(t=t.toLowerCase())[0]?(n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),s(n)):l[t]||e}),u,n):n&&"none"!==n&&e.plugins.autoloader&&(c="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random()),t.attributes.id=c,e.plugins.autoloader.loadLanguages(n,function(){var t=document.getElementById(c);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))}))}}),RegExp(e.languages.markup.tag.pattern.source,"gi")),l={amp:"&",lt:"<",gt:">",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(A),A.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:A.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},A.hooks.add("after-tokenize",function(e){if("graphql"===e.language)for(var t=e.tokens.filter(function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type}),n=0;n<t.length;){var r=t[n++];if("keyword"===r.type&&"mutation"===r.content){var a=[];if(d(["definition-mutation","punctuation"])&&"("===u(1).content){n+=2;var o=f(/^\($/,/^\)$/);if(-1===o)continue;for(;n<o;n++){var i=u(0);"variable"===i.type&&(p(i,"variable-input"),a.push(i.content))}n=o+1}if(d(["punctuation","property-query"])&&"{"===u(0).content&&(n++,p(u(0),"property-mutation"),0<a.length)){var l=f(/^\{$/,/^\}$/);if(-1!==l)for(var s=n;s<l;s++){var c=t[s];"variable"===c.type&&0<=a.indexOf(c.content)&&p(c,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n<e.length;n++){var r=u(n+t);if(!r||r.type!==e[n])return}return 1}function f(e,r){for(var a=1,o=n;o<t.length;o++){var i=t[o],l=i.content;if("punctuation"===i.type&&"string"==typeof l)if(e.test(l))a++;else if(r.test(l)&&0===--a)return o}return-1}function p(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}}),A.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(t,n,r){return t={code:t,grammar:n,language:r},e.hooks.run("before-tokenize",t),t.tokens=e.tokenize(t.code,t.grammar),e.hooks.run("after-tokenize",t),t.tokens}function s(t,n,i){var s=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),c=0,u={},d=(s=l(s.map(function(e){if("string"==typeof e)return e;var n,r;for(e=e.content;-1!==t.indexOf((r=c++,n="___"+i.toUpperCase()+"_"+r+"___")););return u[n]=e,n}).join(""),n,i),Object.keys(u));return c=0,function t(n){for(var o=0;o<n.length;o++){if(c>=d.length)return;var i,s,f,p,h,m,g,b=n[o];"string"==typeof b||"string"==typeof b.content?(i=d[c],-1!==(g=(m="string"==typeof b?b:b.content).indexOf(i))&&(++c,s=m.substring(0,g),h=u[i],f=void 0,(p={})["interpolation-punctuation"]=a,3===(p=e.tokenize(h,p)).length&&((f=[1,1]).push.apply(f,l(p[1],e.languages.javascript,"javascript")),p.splice.apply(p,f)),f=new e.Token("interpolation",p,r.alias,h),p=m.substring(g+i.length),h=[],s&&h.push(s),h.push(f),p&&(t(m=[p]),h.push.apply(h,m)),"string"==typeof b?(n.splice.apply(n,[o,1].concat(h)),o+=h.length-1):b.content=h)):(g=b.content,Array.isArray(g)?t(g):t([g]))}}(s),new e.Token(i,s,"language-"+i,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var c={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function u(e){return"string"==typeof e?e:Array.isArray(e)?e.map(u).join(""):u(e.content)}e.hooks.add("after-tokenize",function(t){t.language in c&&function t(n){for(var r=0,a=n.length;r<a;r++){var o,i,l,c=n[r];"string"!=typeof c&&(o=c.content,Array.isArray(o)?"template-string"===c.type?(c=o[1],3===o.length&&"string"!=typeof c&&"embedded-code"===c.type&&(i=u(c),c=c.alias,c=Array.isArray(c)?c[0]:c,l=e.languages[c])&&(o[1]=s(i,l,c))):t(o):"string"!=typeof o&&t([o]))}}(t.tokens)})}(A),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(A),function(e){var t=e.languages.javascript,n=/\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})+\}/.source,r="(@(?:arg|argument|param|property)\\s+(?:"+n+"\\s+)?)";e.languages.jsdoc=e.languages.extend("javadoclike",{parameter:{pattern:RegExp(r+/(?:(?!\s)[$\w\xA0-\uFFFF.])+(?=\s|$)/.source),lookbehind:!0,inside:{punctuation:/\./}}}),e.languages.insertBefore("jsdoc","keyword",{"optional-parameter":{pattern:RegExp(r+/\[(?:(?!\s)[$\w\xA0-\uFFFF.])+(?:=[^[\]]+)?\](?=\s|$)/.source),lookbehind:!0,inside:{parameter:{pattern:/(^\[)[$\w\xA0-\uFFFF\.]+/,lookbehind:!0,inside:{punctuation:/\./}},code:{pattern:/(=)[\s\S]*(?=\]$)/,lookbehind:!0,inside:t,alias:"language-javascript"},punctuation:/[=[\]]/}},"class-name":[{pattern:RegExp(/(@(?:augments|class|extends|interface|memberof!?|template|this|typedef)\s+(?:<TYPE>\s+)?)[A-Z]\w*(?:\.[A-Z]\w*)*/.source.replace(/<TYPE>/g,function(){return n})),lookbehind:!0,inside:{punctuation:/\./}},{pattern:RegExp("(@[a-z]+\\s+)"+n),lookbehind:!0,inside:{string:t.string,number:t.number,boolean:t.boolean,keyword:e.languages.typescript.keyword,operator:/=>|\.\.\.|[&|?:*]/,punctuation:/[.,;=<>{}()[\]]/}}],example:{pattern:/(@example\s+(?!\s))(?:[^@\s]|\s+(?!\s))+?(?=\s*(?:\*\s*)?(?:@\w|\*\/))/,lookbehind:!0,inside:{code:{pattern:/^([\t ]*(?:\*\s*)?)\S.*$/m,lookbehind:!0,inside:t,alias:"language-javascript"}}}}),e.languages.javadoclike.addSupport("javascript",e.languages.jsdoc)}(A),function(e){e.languages.flow=e.languages.extend("javascript",{}),e.languages.insertBefore("flow","keyword",{type:[{pattern:/\b(?:[Bb]oolean|Function|[Nn]umber|[Ss]tring|[Ss]ymbol|any|mixed|null|void)\b/,alias:"class-name"}]}),e.languages.flow["function-variable"].pattern=/(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/i,delete e.languages.flow.parameter,e.languages.insertBefore("flow","operator",{"flow-punctuation":{pattern:/\{\||\|\}/,alias:"punctuation"}}),Array.isArray(e.languages.flow.keyword)||(e.languages.flow.keyword=[e.languages.flow.keyword]),e.languages.flow.keyword.unshift({pattern:/(^|[^$]\b)(?:Class|declare|opaque|type)\b(?!\$)/,lookbehind:!0},{pattern:/(^|[^$]\B)\$(?:Diff|Enum|Exact|Keys|ObjMap|PropertyType|Record|Shape|Subtype|Supertype|await)\b(?!\$)/,lookbehind:!0})}(A),A.languages.n4js=A.languages.extend("javascript",{keyword:/\b(?:Array|any|boolean|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|module|new|null|number|package|private|protected|public|return|set|static|string|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/}),A.languages.insertBefore("n4js","constant",{annotation:{pattern:/@+\w+/,alias:"operator"}}),A.languages.n4jsd=A.languages.n4js,function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source}),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r<n.length;r++){var a=n[r],o=e.languages.javascript[a];a=(o="RegExp"===e.util.type(o)?e.languages.javascript[a]={pattern:o}:o).inside||{};(o.inside=a)["maybe-class-name"]=/^[A-Z][\s\S]*/}}(A),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,a=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function o(e,t){return e=e.replace(/<S>/g,function(){return n}).replace(/<BRACES>/g,function(){return r}).replace(/<SPREAD>/g,function(){return a}),RegExp(e,t)}function i(t){for(var n=[],r=0;r<t.length;r++){var a=t[r],o=!1;"string"!=typeof a&&("tag"===a.type&&a.content[0]&&"tag"===a.content[0].type?"</"===a.content[0].content[0].content?0<n.length&&n[n.length-1].tagName===l(a.content[0].content[1])&&n.pop():"/>"!==a.content[a.content.length-1].content&&n.push({tagName:l(a.content[0].content[1]),openedBraces:0}):0<n.length&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:0<n.length&&0<n[n.length-1].openedBraces&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&0<n.length&&0===n[n.length-1].openedBraces&&(o=l(a),r<t.length-1&&("string"==typeof t[r+1]||"plain-text"===t[r+1].type)&&(o+=l(t[r+1]),t.splice(r+1,1)),0<r&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(o=l(t[r-1])+o,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",o,null,o)),a.content&&"string"!=typeof a.content&&i(a.content)}}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var l=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(l).join(""):""};e.hooks.add("after-tokenize",function(e){"jsx"!==e.language&&"tsx"!==e.language||i(e.tokens)})}(A),function(e){var t=e.util.clone(e.languages.typescript);(t=(e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"],e.languages.tsx.tag)).pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+t.pattern.source+")",t.pattern.flags),t.lookbehind=!0}(A),A.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp(/(^|[^"#])/.source+"(?:"+/"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source+"|"+/"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source+")"+/(?!["#])/.source),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp(/(^|[^"#])(#+)/.source+"(?:"+/"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source+"|"+/"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source+")\\2"),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp(/#/.source+"(?:"+/(?:elseif|if)\b/.source+"(?:[ \t]*"+/(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source+")+|"+/(?:else|endif)\b/.source+")"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},A.languages.swift["string-literal"].forEach(function(e){e.inside.interpolation.inside=A.languages.swift}),function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(A),A.languages.c=A.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),A.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),A.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},A.languages.c.string],char:A.languages.c.char,comment:A.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:A.languages.c}}}}),A.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete A.languages.c.boolean,A.languages.objectivec=A.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete A.languages.objectivec["class-name"],A.languages.objc=A.languages.objectivec,A.languages.reason=A.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),A.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete A.languages.reason.function,function(e){for(var t=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source,n=0;n<2;n++)t=t.replace(/<self>/g,function(){return t});t=t.replace(/<self>/g,function(){return/[^\s\S]/.source}),e.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(A),A.languages.go=A.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),A.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete A.languages.go["class-name"],function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,function(){return t.source});e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,function(){return t.source})),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,function(){return n})+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(A),A.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},A.languages.python["string-interpolation"].inside.interpolation.inside.rest=A.languages.python,A.languages.py=A.languages.python,A.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},A.languages.webmanifest=A.languages.json;((e,t)=>{for(var n in t)p(e,n,{get:t[n],enumerable:!0})})({},{dracula:()=>L,duotoneDark:()=>T,duotoneLight:()=>j,github:()=>P,gruvboxMaterialDark:()=>Q,gruvboxMaterialLight:()=>K,jettwaveDark:()=>H,jettwaveLight:()=>G,nightOwl:()=>M,nightOwlLight:()=>N,oceanicNext:()=>D,okaidia:()=>B,oneDark:()=>V,oneLight:()=>W,palenight:()=>F,shadesOfPurple:()=>I,synthwave84:()=>z,ultramin:()=>$,vsDark:()=>U,vsLight:()=>q});var L={plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},T={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]},j={plain:{backgroundColor:"#faf8f5",color:"#728fcb"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#b6ad9a"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#063289"}},{types:["property","function"],style:{color:"#b29762"}},{types:["tag-id","selector","atrule-id"],style:{color:"#2d2006"}},{types:["attr-name"],style:{color:"#896724"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule"],style:{color:"#728fcb"}},{types:["placeholder","variable"],style:{color:"#93abdc"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#896724"}}]},P={plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},M={plain:{color:"#d6deeb",backgroundColor:"#011627"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(99, 119, 119)",fontStyle:"italic"}},{types:["string","url"],style:{color:"rgb(173, 219, 103)"}},{types:["variable"],style:{color:"rgb(214, 222, 235)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation"],style:{color:"rgb(199, 146, 234)"}},{types:["selector","doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(255, 203, 139)"}},{types:["tag","operator","keyword"],style:{color:"rgb(127, 219, 202)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["property"],style:{color:"rgb(128, 203, 196)"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}}]},N={plain:{color:"#403f53",backgroundColor:"#FBFBFB"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(72, 118, 214)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(152, 159, 177)",fontStyle:"italic"}},{types:["string","builtin","char","constant","url"],style:{color:"rgb(72, 118, 214)"}},{types:["variable"],style:{color:"rgb(201, 103, 101)"}},{types:["number"],style:{color:"rgb(170, 9, 130)"}},{types:["punctuation"],style:{color:"rgb(153, 76, 195)"}},{types:["function","selector","doctype"],style:{color:"rgb(153, 76, 195)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(17, 17, 17)"}},{types:["tag"],style:{color:"rgb(153, 76, 195)"}},{types:["operator","property","keyword","namespace"],style:{color:"rgb(12, 150, 155)"}},{types:["boolean"],style:{color:"rgb(188, 84, 84)"}}]},O="#c5a5c5",R="#8dc891",D={plain:{backgroundColor:"#282c34",color:"#ffffff"},styles:[{types:["attr-name"],style:{color:O}},{types:["attr-value"],style:{color:R}},{types:["comment","block-comment","prolog","doctype","cdata","shebang"],style:{color:"#999999"}},{types:["property","number","function-name","constant","symbol","deleted"],style:{color:"#5a9bcf"}},{types:["boolean"],style:{color:"#ff8b50"}},{types:["tag"],style:{color:"#fc929e"}},{types:["string"],style:{color:R}},{types:["punctuation"],style:{color:R}},{types:["selector","char","builtin","inserted"],style:{color:"#D8DEE9"}},{types:["function"],style:{color:"#79b6f2"}},{types:["operator","entity","url","variable"],style:{color:"#d7deea"}},{types:["keyword"],style:{color:O}},{types:["atrule","class-name"],style:{color:"#FAC863"}},{types:["important"],style:{fontWeight:"400"}},{types:["bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}}]},B={plain:{color:"#f8f8f2",backgroundColor:"#272822"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"#f92672",fontStyle:"italic"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"#8292a2",fontStyle:"italic"}},{types:["string","url"],style:{color:"#a6e22e"}},{types:["variable"],style:{color:"#f8f8f2"}},{types:["number"],style:{color:"#ae81ff"}},{types:["builtin","char","constant","function","class-name"],style:{color:"#e6db74"}},{types:["punctuation"],style:{color:"#f8f8f2"}},{types:["selector","doctype"],style:{color:"#a6e22e",fontStyle:"italic"}},{types:["tag","operator","keyword"],style:{color:"#66d9ef"}},{types:["boolean"],style:{color:"#ae81ff"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)",opacity:.7}},{types:["tag","property"],style:{color:"#f92672"}},{types:["attr-name"],style:{color:"#a6e22e !important"}},{types:["doctype"],style:{color:"#8292a2"}},{types:["rule"],style:{color:"#e6db74"}}]},F={plain:{color:"#bfc7d5",backgroundColor:"#292d3e"},styles:[{types:["comment"],style:{color:"rgb(105, 112, 152)",fontStyle:"italic"}},{types:["string","inserted"],style:{color:"rgb(195, 232, 141)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation","selector"],style:{color:"rgb(199, 146, 234)"}},{types:["variable"],style:{color:"rgb(191, 199, 213)"}},{types:["class-name","attr-name"],style:{color:"rgb(255, 203, 107)"}},{types:["tag","deleted"],style:{color:"rgb(255, 85, 114)"}},{types:["operator"],style:{color:"rgb(137, 221, 255)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["keyword"],style:{fontStyle:"italic"}},{types:["doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}},{types:["url"],style:{color:"rgb(221, 221, 221)"}}]},I={plain:{color:"#9EFEFF",backgroundColor:"#2D2A55"},styles:[{types:["changed"],style:{color:"rgb(255, 238, 128)"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)"}},{types:["comment"],style:{color:"rgb(179, 98, 255)",fontStyle:"italic"}},{types:["punctuation"],style:{color:"rgb(255, 255, 255)"}},{types:["constant"],style:{color:"rgb(255, 98, 140)"}},{types:["string","url"],style:{color:"rgb(165, 255, 144)"}},{types:["variable"],style:{color:"rgb(255, 238, 128)"}},{types:["number","boolean"],style:{color:"rgb(255, 98, 140)"}},{types:["attr-name"],style:{color:"rgb(255, 180, 84)"}},{types:["keyword","operator","property","namespace","tag","selector","doctype"],style:{color:"rgb(255, 157, 0)"}},{types:["builtin","char","constant","function","class-name"],style:{color:"rgb(250, 208, 0)"}}]},z={plain:{backgroundColor:"linear-gradient(to bottom, #2a2139 75%, #34294f)",backgroundImage:"#34294f",color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"},styles:[{types:["comment","block-comment","prolog","doctype","cdata"],style:{color:"#495495",fontStyle:"italic"}},{types:["punctuation"],style:{color:"#ccc"}},{types:["tag","attr-name","namespace","number","unit","hexcode","deleted"],style:{color:"#e2777a"}},{types:["property","selector"],style:{color:"#72f1b8",textShadow:"0 0 2px #100c0f, 0 0 10px #257c5575, 0 0 35px #21272475"}},{types:["function-name"],style:{color:"#6196cc"}},{types:["boolean","selector-id","function"],style:{color:"#fdfdfd",textShadow:"0 0 2px #001716, 0 0 3px #03edf975, 0 0 5px #03edf975, 0 0 8px #03edf975"}},{types:["class-name","maybe-class-name","builtin"],style:{color:"#fff5f6",textShadow:"0 0 2px #000, 0 0 10px #fc1f2c75, 0 0 5px #fc1f2c75, 0 0 25px #fc1f2c75"}},{types:["constant","symbol"],style:{color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"}},{types:["important","atrule","keyword","selector-class"],style:{color:"#f4eee4",textShadow:"0 0 2px #393a33, 0 0 8px #f39f0575, 0 0 2px #f39f0575"}},{types:["string","char","attr-value","regex","variable"],style:{color:"#f87c32"}},{types:["parameter"],style:{fontStyle:"italic"}},{types:["entity","url"],style:{color:"#67cdcc"}},{types:["operator"],style:{color:"ffffffee"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["entity"],style:{cursor:"help"}},{types:["inserted"],style:{color:"green"}}]},$={plain:{color:"#282a2e",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(197, 200, 198)"}},{types:["string","number","builtin","variable"],style:{color:"rgb(150, 152, 150)"}},{types:["class-name","function","tag","attr-name"],style:{color:"rgb(40, 42, 46)"}}]},U={plain:{color:"#9CDCFE",backgroundColor:"#1E1E1E"},styles:[{types:["prolog"],style:{color:"rgb(0, 0, 128)"}},{types:["comment"],style:{color:"rgb(106, 153, 85)"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"rgb(86, 156, 214)"}},{types:["number","inserted"],style:{color:"rgb(181, 206, 168)"}},{types:["constant"],style:{color:"rgb(100, 102, 149)"}},{types:["attr-name","variable"],style:{color:"rgb(156, 220, 254)"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"rgb(206, 145, 120)"}},{types:["selector"],style:{color:"rgb(215, 186, 125)"}},{types:["tag"],style:{color:"rgb(78, 201, 176)"}},{types:["tag"],languages:["markup"],style:{color:"rgb(86, 156, 214)"}},{types:["punctuation","operator"],style:{color:"rgb(212, 212, 212)"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"rgb(220, 220, 170)"}},{types:["class-name"],style:{color:"rgb(78, 201, 176)"}},{types:["char"],style:{color:"rgb(209, 105, 105)"}}]},q={plain:{color:"#000000",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(0, 128, 0)"}},{types:["builtin"],style:{color:"rgb(0, 112, 193)"}},{types:["number","variable","inserted"],style:{color:"rgb(9, 134, 88)"}},{types:["operator"],style:{color:"rgb(0, 0, 0)"}},{types:["constant","char"],style:{color:"rgb(129, 31, 63)"}},{types:["tag"],style:{color:"rgb(128, 0, 0)"}},{types:["attr-name"],style:{color:"rgb(255, 0, 0)"}},{types:["deleted","string"],style:{color:"rgb(163, 21, 21)"}},{types:["changed","punctuation"],style:{color:"rgb(4, 81, 165)"}},{types:["function","keyword"],style:{color:"rgb(0, 0, 255)"}},{types:["class-name"],style:{color:"rgb(38, 127, 153)"}}]},H={plain:{color:"#f8fafc",backgroundColor:"#011627"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#569CD6"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#f8fafc"}},{types:["attr-name","variable"],style:{color:"#9CDCFE"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#cbd5e1"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#D4D4D4"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#7dd3fc"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},G={plain:{color:"#0f172a",backgroundColor:"#f1f5f9"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#0c4a6e"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#0f172a"}},{types:["attr-name","variable"],style:{color:"#0c4a6e"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#64748b"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#475569"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#0e7490"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},V={plain:{backgroundColor:"hsl(220, 13%, 18%)",color:"hsl(220, 14%, 71%)",textShadow:"0 1px rgba(0, 0, 0, 0.3)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(220, 10%, 40%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(220, 14%, 71%)"}},{types:["attr-name","class-name","maybe-class-name","boolean","constant","number","atrule"],style:{color:"hsl(29, 54%, 61%)"}},{types:["keyword"],style:{color:"hsl(286, 60%, 67%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(355, 65%, 65%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value"],style:{color:"hsl(95, 38%, 62%)"}},{types:["variable","operator","function"],style:{color:"hsl(207, 82%, 66%)"}},{types:["url"],style:{color:"hsl(187, 47%, 55%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(220, 14%, 71%)"}}]},W={plain:{backgroundColor:"hsl(230, 1%, 98%)",color:"hsl(230, 8%, 24%)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(230, 4%, 64%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(230, 8%, 24%)"}},{types:["attr-name","class-name","boolean","constant","number","atrule"],style:{color:"hsl(35, 99%, 36%)"}},{types:["keyword"],style:{color:"hsl(301, 63%, 40%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(5, 74%, 59%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value","punctuation"],style:{color:"hsl(119, 34%, 47%)"}},{types:["variable","operator","function"],style:{color:"hsl(221, 87%, 60%)"}},{types:["url"],style:{color:"hsl(198, 99%, 37%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(230, 8%, 24%)"}}]},Q={plain:{color:"#ebdbb2",backgroundColor:"#292828"},styles:[{types:["imports","class-name","maybe-class-name","constant","doctype","builtin","function"],style:{color:"#d8a657"}},{types:["property-access"],style:{color:"#7daea3"}},{types:["tag"],style:{color:"#e78a4e"}},{types:["attr-name","char","url","regex"],style:{color:"#a9b665"}},{types:["attr-value","string"],style:{color:"#89b482"}},{types:["comment","prolog","cdata","operator","inserted"],style:{color:"#a89984"}},{types:["delimiter","boolean","keyword","selector","important","atrule","property","variable","deleted"],style:{color:"#ea6962"}},{types:["entity","number","symbol"],style:{color:"#d3869b"}}]},K={plain:{color:"#654735",backgroundColor:"#f9f5d7"},styles:[{types:["delimiter","boolean","keyword","selector","important","atrule","property","variable","deleted"],style:{color:"#af2528"}},{types:["imports","class-name","maybe-class-name","constant","doctype","builtin"],style:{color:"#b4730e"}},{types:["string","attr-value"],style:{color:"#477a5b"}},{types:["property-access"],style:{color:"#266b79"}},{types:["function","attr-name","char","url"],style:{color:"#72761e"}},{types:["tag"],style:{color:"#b94c07"}},{types:["comment","prolog","cdata","operator","inserted"],style:{color:"#a89984"}},{types:["entity","number","symbol"],style:{color:"#924f79"}}]},Y=/\r\n|\r|\n/,X=e=>{0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},Z=(e,t)=>{const n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)},J=e=>{const t=[[]],n=[e],r=[0],a=[e.length];let o=0,i=0,l=[];const s=[l];for(;i>-1;){for(;(o=r[i]++)<a[i];){let e,c=t[i];const u=n[i][o];if("string"==typeof u?(c=i>0?c:["plain"],e=u):(c=Z(c,u.type),u.alias&&(c=Z(c,u.alias)),e=u.content),"string"!=typeof e){i++,t.push(c),n.push(e),r.push(0),a.push(e.length);continue}const d=e.split(Y),f=d.length;l.push({types:c,content:d[0]});for(let t=1;t<f;t++)X(l),s.push(l=[]),l.push({types:c,content:d[t]})}i--,t.pop(),n.pop(),r.pop(),a.pop()}return X(l),s},ee=(e,t)=>{const{plain:n}=e,r=e.styles.reduce((e,n)=>{const{languages:r,style:a}=n;return r&&!r.includes(t)||n.types.forEach(t=>{const n=x(x({},e[t]),a);e[t]=n}),e},{});return r.root=n,r.plain=_(x({},n),{backgroundColor:void 0}),r},te=({children:e,language:t,code:n,theme:r,prism:a})=>{const o=t.toLowerCase(),i=ee(r,o),l=(e=>(0,u.useCallback)(t=>{var n=t,{className:r,style:a,line:o}=n,i=E(n,["className","style","line"]);const l=_(x({},i),{className:(0,d.A)("token-line",r)});return"object"==typeof e&&"plain"in e&&(l.style=e.plain),"object"==typeof a&&(l.style=x(x({},l.style||{}),a)),l},[e]))(i),s=(e=>{const t=(0,u.useCallback)(({types:t,empty:n})=>{if(null!=e)return 1===t.length&&"plain"===t[0]?null!=n?{display:"inline-block"}:void 0:1===t.length&&null!=n?e[t[0]]:Object.assign(null!=n?{display:"inline-block"}:{},...t.map(t=>e[t]))},[e]);return(0,u.useCallback)(e=>{var n=e,{token:r,className:a,style:o}=n,i=E(n,["token","className","style"]);const l=_(x({},i),{className:(0,d.A)("token",...r.types,a),children:r.content,style:t(r)});return null!=o&&(l.style=x(x({},l.style||{}),o)),l},[t])})(i),c=(({prism:e,code:t,grammar:n,language:r})=>(0,u.useMemo)(()=>{if(null==n)return J([t]);const a={code:t,grammar:n,language:r,tokens:[]};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(t,n),e.hooks.run("after-tokenize",a),J(a.tokens)},[t,n,r,e]))({prism:a,language:o,code:n,grammar:a.languages[o]});return e({tokens:c,className:`prism-code language-${o}`,style:null!=i?i.root:{},getLineProps:l,getTokenProps:s})},ne=e=>(0,u.createElement)(te,_(x({},e),{prism:e.prism||A,theme:e.theme||U,code:e.code,language:e.language}))},2131:(e,t,n)=>{"use strict";n.d(t,{o:()=>i});var r=n(4586),a=n(6347),o=n(440);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:l}}=(0,r.A)(),{pathname:s}=(0,a.zy)(),c=(0,o.Ks)(s,{trailingSlash:n,baseUrl:e}),u=l===i?e:e.replace(`/${l}/`,"/"),d=c.replace(e,"");return{createUrl:function({locale:e,fullyQualified:n}){return`${n?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(e)}${d}`}}}},2303:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(6125);function o(){return(0,r.useContext)(a.o)}},2566:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addPrefix=function(e,t){return e.startsWith(t)?e:`${t}${e}`},t.removeSuffix=function(e,t){if(""===t)return e;return e.endsWith(t)?e.slice(0,-t.length):e},t.addSuffix=function(e,t){return e.endsWith(t)?e:`${e}${t}`},t.removePrefix=function(e,t){return e.startsWith(t)?e.slice(t.length):e}},2654:e=>{"use strict";e.exports={}},2694:(e,t,n)=>{"use strict";var r=n(6925);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},2799:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,a=n?Symbol.for("react.portal"):60106,o=n?Symbol.for("react.fragment"):60107,i=n?Symbol.for("react.strict_mode"):60108,l=n?Symbol.for("react.profiler"):60114,s=n?Symbol.for("react.provider"):60109,c=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,d=n?Symbol.for("react.concurrent_mode"):60111,f=n?Symbol.for("react.forward_ref"):60112,p=n?Symbol.for("react.suspense"):60113,h=n?Symbol.for("react.suspense_list"):60120,m=n?Symbol.for("react.memo"):60115,g=n?Symbol.for("react.lazy"):60116,b=n?Symbol.for("react.block"):60121,y=n?Symbol.for("react.fundamental"):60117,v=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function k(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case u:case d:case o:case l:case i:case p:return e;default:switch(e=e&&e.$$typeof){case c:case f:case g:case m:case s:return e;default:return t}}case a:return t}}}function S(e){return k(e)===d}t.AsyncMode=u,t.ConcurrentMode=d,t.ContextConsumer=c,t.ContextProvider=s,t.Element=r,t.ForwardRef=f,t.Fragment=o,t.Lazy=g,t.Memo=m,t.Portal=a,t.Profiler=l,t.StrictMode=i,t.Suspense=p,t.isAsyncMode=function(e){return S(e)||k(e)===u},t.isConcurrentMode=S,t.isContextConsumer=function(e){return k(e)===c},t.isContextProvider=function(e){return k(e)===s},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return k(e)===f},t.isFragment=function(e){return k(e)===o},t.isLazy=function(e){return k(e)===g},t.isMemo=function(e){return k(e)===m},t.isPortal=function(e){return k(e)===a},t.isProfiler=function(e){return k(e)===l},t.isStrictMode=function(e){return k(e)===i},t.isSuspense=function(e){return k(e)===p},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===o||e===d||e===l||e===i||e===p||e===h||"object"==typeof e&&null!==e&&(e.$$typeof===g||e.$$typeof===m||e.$$typeof===s||e.$$typeof===c||e.$$typeof===f||e.$$typeof===y||e.$$typeof===v||e.$$typeof===w||e.$$typeof===b)},t.typeOf=k},2831:(e,t,n)=>{"use strict";n.d(t,{u:()=>i,v:()=>l});var r=n(6347),a=n(8168),o=n(6540);function i(e,t,n){return void 0===n&&(n=[]),e.some(function(e){var a=e.path?(0,r.B6)(t,e):n.length?n[n.length-1].match:r.Ix.computeRootMatch(t);return a&&(n.push({route:e,match:a}),e.routes&&i(e.routes,t,n)),a}),n}function l(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?o.createElement(r.dO,n,e.map(function(e,n){return o.createElement(r.qh,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,a.A)({},n,{},t,{route:e})):o.createElement(e.component,(0,a.A)({},n,t,{route:e}))}})})):null}},2833:e=>{e.exports=function(e,t,n,r){var a=n?n.call(r,e,t):void 0;if(void 0!==a)return!!a;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var o=Object.keys(e),i=Object.keys(t);if(o.length!==i.length)return!1;for(var l=Object.prototype.hasOwnProperty.bind(t),s=0;s<o.length;s++){var c=o[s];if(!l(c))return!1;var u=e[c],d=t[c];if(!1===(a=n?n.call(r,u,d,c):void 0)||void 0===a&&u!==d)return!1}return!0}},2892:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function a(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{A:()=>a})},2983:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addTrailingSlash=a,t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[i]=e.split(/[#?]/),l="/"===i||i===r?i:(s=i,c=n,c?a(s):o(s));var s,c;return e.replace(i,l)},t.addLeadingSlash=function(e){return(0,r.addPrefix)(e,"/")},t.removeTrailingSlash=o;const r=n(2566);function a(e){return e.endsWith("/")?e:`${e}/`}function o(e){return(0,r.removeSuffix)(e,"/")}},3001:(e,t,n)=>{"use strict";n.r(t)},3025:(e,t,n)=>{"use strict";n.d(t,{n:()=>l,r:()=>s});var r=n(6540),a=n(9532),o=n(4848);const i=r.createContext(null);function l({children:e,version:t}){return(0,o.jsx)(i.Provider,{value:t,children:e})}function s(){const e=(0,r.useContext)(i);if(null===e)throw new a.dV("DocsVersionProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{W:()=>i,o:()=>o});var r=n(6540),a=n(4848);const o=r.createContext(null);function i({children:e,value:t}){const n=r.useContext(o),i=(0,r.useMemo)(()=>function({parent:e,value:t}){if(!e){if(!t)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in t))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return t}const n={...e.data,...t?.data};return{plugin:e.plugin,data:n}}({parent:n,value:t}),[n,t]);return(0,a.jsx)(o.Provider,{value:i,children:e})}},3104:(e,t,n)=>{"use strict";n.d(t,{Mq:()=>f,Tv:()=>c,gk:()=>p});var r=n(6540),a=n(8193),o=n(2303),i=(n(205),n(9532)),l=n(4848);const s=r.createContext(void 0);function c({children:e}){const t=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)(()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}}),[])}();return(0,l.jsx)(s.Provider,{value:t,children:e})}function u(){const e=(0,r.useContext)(s);if(null==e)throw new i.dV("ScrollControllerProvider");return e}const d=()=>a.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function f(e,t=[]){const{scrollEventsEnabledRef:n}=u(),a=(0,r.useRef)(d()),o=(0,i._q)(e);(0,r.useEffect)(()=>{const e=()=>{if(!n.current)return;const e=d();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)},[o,n,...t])}function p(){const e=(0,r.useRef)(null),t=(0,o.A)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&a<e)&&(t=requestAnimationFrame(r),window.scrollTo(0,Math.floor(.85*(a-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3109:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{O:()=>r})},3157:(e,t,n)=>{var r={"./":8722};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=3157},3186:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});n(6540);const r={iconExternalLink:"iconExternalLink_nPIU"};var a=n(4848);const o="#theme-svg-external-link";function i({width:e=13.5,height:t=13.5}){return(0,a.jsx)("svg",{width:e,height:t,"aria-hidden":"true",className:r.iconExternalLink,children:(0,a.jsx)("use",{href:o})})}},3259:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function a(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n(6540),s=[],c=[];var u=l.createContext(null);function d(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then(function(e){return n.loading=!1,n.loaded=e,e}).catch(function(e){throw n.loading=!1,n.error=e,e}),n}function f(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach(function(r){var a=d(e[r]);a.loading?t.loading=!0:(t.loaded[r]=a.loaded,t.error=a.error),n.push(a.promise),a.promise.then(function(e){t.loaded[r]=e}).catch(function(e){t.error=e})})}catch(r){t.error=r}return t.promise=Promise.all(n).then(function(e){return t.loading=!1,e}).catch(function(e){throw t.loading=!1,e}),t}function p(e,t){return l.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function h(e,t){var d,f;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var h=i({loader:null,loading:null,delay:200,timeout:null,render:p,webpack:null,modules:null},t),m=null;function g(){return m||(m=e(h.loader)),m.promise}return s.push(g),"function"==typeof h.webpack&&c.push(function(){if((0,h.webpack)().every(function(e){return void 0!==e&&void 0!==n.m[e]}))return g()}),f=d=function(t){function n(n){var r;return o(a(a(r=t.call(this,n)||this)),"retry",function(){r.setState({error:null,loading:!0,timedOut:!1}),m=e(h.loader),r._loadModule()}),g(),r.state={error:m.error,pastDelay:!1,timedOut:!1,loading:m.loading,loaded:m.loaded},r}r(n,t),n.preload=function(){return g()};var i=n.prototype;return i.UNSAFE_componentWillMount=function(){this._loadModule()},i.componentDidMount=function(){this._mounted=!0},i._loadModule=function(){var e=this;if(this.context&&Array.isArray(h.modules)&&h.modules.forEach(function(t){e.context.report(t)}),m.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof h.delay&&(0===h.delay?this.setState({pastDelay:!0}):this._delay=setTimeout(function(){t({pastDelay:!0})},h.delay)),"number"==typeof h.timeout&&(this._timeout=setTimeout(function(){t({timedOut:!0})},h.timeout));var n=function(){t({error:m.error,loaded:m.loaded,loading:m.loading}),e._clearTimeouts()};m.promise.then(function(){return n(),null}).catch(function(e){return n(),null})}},i.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},i._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},i.render=function(){return this.state.loading||this.state.error?l.createElement(h.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?h.render(this.state.loaded,this.props):null},n}(l.Component),o(d,"contextType",u),f}function m(e){return h(d,e)}m.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return h(f,e)};var g=function(e){function t(){return e.apply(this,arguments)||this}return r(t,e),t.prototype.render=function(){return l.createElement(u.Provider,{value:{report:this.props.report}},l.Children.only(this.props.children))},t}(l.Component);function b(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then(function(){if(e.length)return b(e)})}m.Capture=g,m.preloadAll=function(){return new Promise(function(e,t){b(s).then(e,t)})},m.preloadReady=function(){return new Promise(function(e,t){b(c).then(e,e)})},e.exports=m},3427:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});var r=n(6540);n(4848);const a=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),o=()=>(0,r.useContext)(a);function i(){return o()}},3465:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(6540);var r=n(8774),a=n(6025),o=n(4586),i=n(6342),l=n(1122),s=n(4848);function c({logo:e,alt:t,imageClassName:n}){const r={light:(0,a.Ay)(e.src),dark:(0,a.Ay)(e.srcDark||e.src)},o=(0,s.jsx)(l.A,{className:e.className,sources:r,height:e.height,width:e.width,alt:t,style:e.style});return n?(0,s.jsx)("div",{className:n,children:o}):o}function u(e){const{siteConfig:{title:t}}=(0,o.A)(),{navbar:{title:n,logo:l}}=(0,i.p)(),{imageClassName:u,titleClassName:d,...f}=e,p=(0,a.Ay)(l?.href||"/"),h=n?"":t,m=l?.alt??h;return(0,s.jsxs)(r.A,{to:p,...f,...l?.target&&{target:l.target},children:[l&&(0,s.jsx)(c,{logo:l,alt:m,imageClassName:u}),null!=n&&(0,s.jsx)("b",{className:d,children:n})]})}},3886:(e,t,n)=>{"use strict";n.d(t,{VQ:()=>g,g1:()=>y});var r=n(6540),a=n(4070),o=n(7065),i=n(6342),l=n(679),s=n(9532),c=n(4848);const u=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,l.Wf)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,l.Wf)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,l.Wf)(u(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map(e=>[e,{preferredVersionName:null}]));const p=r.createContext(null);function h(){const e=(0,a.Gy)(),t=(0,i.p)().docs.versionPersistence,n=(0,r.useMemo)(()=>Object.keys(e),[e]),[o,l]=(0,r.useState)(()=>f(n));(0,r.useEffect)(()=>{l(function({pluginIds:e,versionPersistence:t,allDocsData:n}){function r(e){const r=d.read(e,t);return n[e].versions.some(e=>e.name===r)?{preferredVersionName:r}:(d.clear(e,t),{preferredVersionName:null})}return Object.fromEntries(e.map(e=>[e,r(e)]))}({allDocsData:e,versionPersistence:t,pluginIds:n}))},[e,t,n]);return[o,(0,r.useMemo)(()=>({savePreferredVersion:function(e,n){d.save(e,t,n),l(t=>({...t,[e]:{preferredVersionName:n}}))}}),[t])]}function m({children:e}){const t=h();return(0,c.jsx)(p.Provider,{value:t,children:e})}function g({children:e}){return(0,c.jsx)(m,{children:e})}function b(){const e=(0,r.useContext)(p);if(!e)throw new s.dV("DocsPreferredVersionContextProvider");return e}function y(e=o.W){const t=(0,a.ht)(e),[n,i]=b(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find(e=>e.name===l)??null,savePreferredVersionName:(0,r.useCallback)(t=>{i.savePreferredVersion(e,t)},[i,e])}}},4054:e=>{"use strict";e.exports=JSON.parse('{"/BharatMLStack/blog-f21":{"__comp":"a6aa9e1f","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"f9755c6e"},{"content":"fccc4c42"},{"content":"fccc4c42"},{"content":"a97f18d9"},{"content":"f2c141e4"}],"__props":"f994c8da"},"/BharatMLStack/blog/archive-dde":{"__comp":"9e4087bc","__context":{"plugin":"36994c47"},"__props":"6479fb86"},"/BharatMLStack/blog/authors-f47":{"__comp":"621db11d","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","__props":"2d865531"},"/BharatMLStack/blog/post-five-0ec":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"3aeb33c7"},"/BharatMLStack/blog/post-one-e5f":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"09dd5be9"},"/BharatMLStack/blog/post-three-be5":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"79ae4ea7"},"/BharatMLStack/blog/post-three-85f":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"428aafcc"},"/BharatMLStack/blog/post-two-5a0":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"00b12b9c"},"/BharatMLStack/blog/tags-8af":{"__comp":"01a85c17","__context":{"plugin":"36994c47"},"sidebar":"814f3328","__props":"7fa80e1c"},"/BharatMLStack/blog/tags/bharatmlstack-0c5":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"f9755c6e"},{"content":"fccc4c42"},{"content":"fccc4c42"},{"content":"a97f18d9"}],"__props":"aaabe254"},"/BharatMLStack/blog/tags/embedding-search-27a":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"fccc4c42"}],"__props":"be9e6e2d"},"/BharatMLStack/blog/tags/inferflow-9d9":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"a97f18d9"}],"__props":"93f344c7"},"/BharatMLStack/blog/tags/interaction-store-c75":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"a97f18d9"},{"content":"f2c141e4"}],"__props":"3980073a"},"/BharatMLStack/blog/tags/llm-fa9":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"f9755c6e"},{"content":"fccc4c42"}],"__props":"adb039a4"},"/BharatMLStack/blog/tags/meesho-e82":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"f9755c6e"},{"content":"fccc4c42"},{"content":"fccc4c42"},{"content":"a97f18d9"},{"content":"f2c141e4"}],"__props":"1a64de69"},"/BharatMLStack/blog/tags/mlplatform-856":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"f9755c6e"},{"content":"fccc4c42"},{"content":"fccc4c42"},{"content":"a97f18d9"},{"content":"f2c141e4"}],"__props":"479eb034"},"/BharatMLStack/blog/tags/model-inference-efa":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"fccc4c42"}],"__props":"08daf6b6"},"/BharatMLStack/blog/tags/online-feature-store-44b":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"f2c141e4"}],"__props":"3e1c5046"},"/BharatMLStack/blog/tags/tensorrt-llm-bec":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"f9755c6e"},{"content":"fccc4c42"}],"__props":"99009a21"},"/BharatMLStack/blog/tags/vllm-bd3":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"f9755c6e"},{"content":"fccc4c42"}],"__props":"6bb91276"},"/BharatMLStack/markdown-page-747":{"__comp":"1f391b9e","__context":{"plugin":"a7456010"},"content":"393be207"},"/BharatMLStack/-e34":{"__comp":"c4f5d8e4","__context":{"plugin":"a7456010"},"config":"5e9f5e1a"},"/BharatMLStack/-c10":{"__comp":"5e95c892","__context":{"plugin":"aba21aa0"}},"/BharatMLStack/-11b":{"__comp":"a7bd4aaa","__props":"4137b431"},"/BharatMLStack/-4d0":{"__comp":"a94703ab"},"/BharatMLStack/category/go-sdk-6b0":{"__comp":"14eb3368","__props":"c7b64fcc"},"/BharatMLStack/category/inferflow-e9f":{"__comp":"14eb3368","__props":"8dd2df60"},"/BharatMLStack/category/numerix-703":{"__comp":"14eb3368","__props":"50899a24"},"/BharatMLStack/category/online-feature-store-7ee":{"__comp":"14eb3368","__props":"8ac6191a"},"/BharatMLStack/category/python-sdk-1fd":{"__comp":"14eb3368","__props":"44d1c015"},"/BharatMLStack/category/quick-start-dff":{"__comp":"14eb3368","__props":"14064408"},"/BharatMLStack/category/sdks-532":{"__comp":"14eb3368","__props":"616111d3"},"/BharatMLStack/category/trufflebox-ui-5f5":{"__comp":"14eb3368","__props":"fcf4f6ca"},"/BharatMLStack/category/v100-ddd":{"__comp":"14eb3368","__props":"fa31f022"},"/BharatMLStack/inferflow/v1.0.0-018":{"__comp":"14eb3368","__props":"45a03d07"},"/BharatMLStack/inferflow/v1.0.0/architecture-46b":{"__comp":"17896441","content":"252a9097"},"/BharatMLStack/inferflow/v1.0.0/configuration-4ef":{"__comp":"17896441","content":"9d13045e"},"/BharatMLStack/inferflow/v1.0.0/functionalities-65a":{"__comp":"17896441","content":"0a89f5c9"},"/BharatMLStack/inferflow/v1.0.0/release-notes-cce":{"__comp":"17896441","content":"9aed321e"},"/BharatMLStack/numerix/v1.0.0-441":{"__comp":"14eb3368","__props":"3216e812"},"/BharatMLStack/numerix/v1.0.0/architecture-4d9":{"__comp":"17896441","content":"4df0e30b"},"/BharatMLStack/numerix/v1.0.0/benchmarks-eae":{"__comp":"17896441","content":"e8202a51"},"/BharatMLStack/numerix/v1.0.0/functionalities-f7b":{"__comp":"17896441","content":"2c62ead1"},"/BharatMLStack/numerix/v1.0.0/release-notes-77b":{"__comp":"17896441","content":"8ea48c46"},"/BharatMLStack/online-feature-store/v1.0.0-218":{"__comp":"14eb3368","__props":"72dc5b25"},"/BharatMLStack/online-feature-store/v1.0.0/architecture-0af":{"__comp":"17896441","content":"e66382f6"},"/BharatMLStack/online-feature-store/v1.0.0/benchmarks-889":{"__comp":"17896441","content":"67d4782a"},"/BharatMLStack/online-feature-store/v1.0.0/data-formats-46e":{"__comp":"17896441","content":"4caa95bf"},"/BharatMLStack/online-feature-store/v1.0.0/functionalities-415":{"__comp":"17896441","content":"c4822c4f"},"/BharatMLStack/online-feature-store/v1.0.0/release-notes-36c":{"__comp":"17896441","content":"d152284c"},"/BharatMLStack/quick-start/v1.0.0/quick-start-b19":{"__comp":"17896441","content":"0fff8dc8"},"/BharatMLStack/sdks/go/v1.0.0/feature_client-1df":{"__comp":"17896441","content":"4af50aac"},"/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client-9dc":{"__comp":"17896441","content":"0413d9af"},"/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client-1bc":{"__comp":"17896441","content":"ac51638e"},"/BharatMLStack/trufflebox-ui/v1.0.0/userguide-65e":{"__comp":"17896441","content":"176d210f"}}')},4070:(e,t,n)=>{"use strict";n.d(t,{zK:()=>m,vT:()=>f,Gy:()=>u,HW:()=>g,ht:()=>d,r7:()=>h,jh:()=>p});var r=n(6347),a=n(4586),o=n(7065);function i(e,t={}){const n=function(){const{globalData:e}=(0,a.A)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find(e=>e.isLast);function s(e,t){const n=function(e,t){return[...e.versions].sort((e,t)=>e.path===t.path?0:e.path.includes(t.path)?-1:t.path.includes(e.path)?1:0).find(e=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1}))}(e,t),a=n?.docs.find(e=>!!(0,r.B6)(t,{path:e.path,exact:!0,strict:!1}));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach(e=>{e.docs.forEach(r=>{r.id===t&&(n[e.name]=r)})}),n}(a.id):{}}}const c={},u=()=>i("docusaurus-plugin-content-docs")??c,d=e=>{try{return function(e,t=o.W,n={}){const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0})}catch(t){throw new Error("You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled"+("Default"===e?"":` (pluginId=${e}`),{cause:t})}};function f(e={}){const t=u(),{pathname:n}=(0,r.zy)();return function(e,t,n={}){const a=Object.entries(e).sort((e,t)=>t[1].path.localeCompare(e[1].path)).find(([,e])=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map(e=>e.path).join(", ")}`);return o}(t,n,e)}function p(e){return d(e).versions}function h(e){const t=d(e);return l(t)}function m(e){const t=d(e),{pathname:n}=(0,r.zy)();return s(t,n)}function g(e){const t=d(e),{pathname:n}=(0,r.zy)();return function(e,t){const n=l(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},4090:(e,t,n)=>{"use strict";n.d(t,{w:()=>a,J:()=>o});var r=n(6540);const a="navigation-with-keyboard";function o(){(0,r.useEffect)(()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}},[])}},4146:(e,t,n)=>{"use strict";var r=n(4363),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||a}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,h=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(h){var a=p(n);a&&a!==h&&e(t,a,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var l=s(t),m=s(n),g=0;g<i.length;++g){var b=i[g];if(!(o[b]||r&&r[b]||m&&m[b]||l&&l[b])){var y=f(n,b);try{c(t,b,y)}catch(v){}}}}return t}},4164:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(n=r(e[t]))&&(a&&(a+=" "),a+=n)}else for(n in e)e[n]&&(a&&(a+=" "),a+=n);return a}n.d(t,{A:()=>a});const a=function(){for(var e,t,n=0,a="",o=arguments.length;n<o;n++)(e=arguments[n])&&(t=r(e))&&(a&&(a+=" "),a+=t);return a}},4363:(e,t,n)=>{"use strict";e.exports=n(2799)},4477:(e,t)=>{"use strict";function n(e,t){var n=e.length;e.push(t);e:for(;0<n;){var r=n-1>>>1,a=e[r];if(!(0<o(a,t)))break e;e[r]=t,e[n]=a,n=r}}function r(e){return 0===e.length?null:e[0]}function a(e){if(0===e.length)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,a=e.length,i=a>>>1;r<i;){var l=2*(r+1)-1,s=e[l],c=l+1,u=e[c];if(0>o(s,n))c<a&&0>o(u,s)?(e[r]=u,e[c]=n,r=c):(e[r]=s,e[l]=n,r=l);else{if(!(c<a&&0>o(u,n)))break e;e[r]=u,e[c]=n,r=c}}}return t}function o(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}if(t.unstable_now=void 0,"object"==typeof performance&&"function"==typeof performance.now){var i=performance;t.unstable_now=function(){return i.now()}}else{var l=Date,s=l.now();t.unstable_now=function(){return l.now()-s}}var c=[],u=[],d=1,f=null,p=3,h=!1,m=!1,g=!1,b=!1,y="function"==typeof setTimeout?setTimeout:null,v="function"==typeof clearTimeout?clearTimeout:null,w="undefined"!=typeof setImmediate?setImmediate:null;function k(e){for(var t=r(u);null!==t;){if(null===t.callback)a(u);else{if(!(t.startTime<=e))break;a(u),t.sortIndex=t.expirationTime,n(c,t)}t=r(u)}}function S(e){if(g=!1,k(e),!m)if(null!==r(c))m=!0,_||(_=!0,x());else{var t=r(u);null!==t&&M(S,t.startTime-e)}}var x,_=!1,E=-1,C=5,A=-1;function L(){return!!b||!(t.unstable_now()-A<C)}function T(){if(b=!1,_){var e=t.unstable_now();A=e;var n=!0;try{e:{m=!1,g&&(g=!1,v(E),E=-1),h=!0;var o=p;try{t:{for(k(e),f=r(c);null!==f&&!(f.expirationTime>e&&L());){var i=f.callback;if("function"==typeof i){f.callback=null,p=f.priorityLevel;var l=i(f.expirationTime<=e);if(e=t.unstable_now(),"function"==typeof l){f.callback=l,k(e),n=!0;break t}f===r(c)&&a(c),k(e)}else a(c);f=r(c)}if(null!==f)n=!0;else{var s=r(u);null!==s&&M(S,s.startTime-e),n=!1}}break e}finally{f=null,p=o,h=!1}n=void 0}}finally{n?x():_=!1}}}if("function"==typeof w)x=function(){w(T)};else if("undefined"!=typeof MessageChannel){var j=new MessageChannel,P=j.port2;j.port1.onmessage=T,x=function(){P.postMessage(null)}}else x=function(){y(T,0)};function M(e,n){E=y(function(){e(t.unstable_now())},n)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):C=0<e?Math.floor(1e3/e):5},t.unstable_getCurrentPriorityLevel=function(){return p},t.unstable_next=function(e){switch(p){case 1:case 2:case 3:var t=3;break;default:t=p}var n=p;p=t;try{return e()}finally{p=n}},t.unstable_requestPaint=function(){b=!0},t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=p;p=e;try{return t()}finally{p=n}},t.unstable_scheduleCallback=function(e,a,o){var i=t.unstable_now();switch("object"==typeof o&&null!==o?o="number"==typeof(o=o.delay)&&0<o?i+o:i:o=i,e){case 1:var l=-1;break;case 2:l=250;break;case 5:l=1073741823;break;case 4:l=1e4;break;default:l=5e3}return e={id:d++,callback:a,priorityLevel:e,startTime:o,expirationTime:l=o+l,sortIndex:-1},o>i?(e.sortIndex=o,n(u,e),null===r(c)&&e===r(u)&&(g?(v(E),E=-1):g=!0,M(S,o-i))):(e.sortIndex=l,n(c,e),m||h||(m=!0,_||(_=!0,x()))),e},t.unstable_shouldYield=L,t.unstable_wrapCallback=function(e){var t=p;return function(){var n=p;p=t;try{return e.apply(this,arguments)}finally{p=n}}}},4563:(e,t,n)=>{"use strict";n.d(t,{AL:()=>u,s$:()=>d});var r=n(6540),a=n(4586),o=n(6803),i=n(9532),l=n(4848);const s=({title:e,siteTitle:t,titleDelimiter:n})=>{const r=e?.trim();return r&&r!==t?`${r} ${n} ${t}`:t},c=(0,r.createContext)(null);function u({formatter:e,children:t}){return(0,l.jsx)(c.Provider,{value:e,children:t})}function d(){const e=function(){const e=(0,r.useContext)(c);if(null===e)throw new i.dV("TitleFormatterProvider");return e}(),{siteConfig:t}=(0,a.A)(),{title:n,titleDelimiter:l}=t,{plugin:u}=(0,o.A)();return{format:t=>e({title:t,siteTitle:n,titleDelimiter:l,plugin:u,defaultFormatter:s})}}},4581:(e,t,n)=>{"use strict";n.d(t,{l:()=>l});var r=n(6540),a=n(8193);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l({desktopBreakpoint:e=i}={}){const[t,n]=(0,r.useState)(()=>"ssr");return(0,r.useEffect)(()=>{function t(){n(function(e){if(!a.A.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?o.desktop:o.mobile}(e))}return t(),window.addEventListener("resize",t),()=>{window.removeEventListener("resize",t)}},[e]),t}},4586:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(6988);function o(){return(0,r.useContext)(a.o)}},4625:(e,t,n)=>{"use strict";n.d(t,{I9:()=>d,Kd:()=>u,N_:()=>b,k2:()=>w});var r=n(6347),a=n(2892),o=n(6540),i=n(1513),l=n(8168),s=n(8587),c=n(1561),u=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,i.zR)(t.props),t}return(0,a.A)(t,e),t.prototype.render=function(){return o.createElement(r.Ix,{history:this.history,children:this.props.children})},t}(o.Component);var d=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,i.TM)(t.props),t}return(0,a.A)(t,e),t.prototype.render=function(){return o.createElement(r.Ix,{history:this.history,children:this.props.children})},t}(o.Component);var f=function(e,t){return"function"==typeof e?e(t):e},p=function(e,t){return"string"==typeof e?(0,i.yJ)(e,null,null,t):e},h=function(e){return e},m=o.forwardRef;void 0===m&&(m=h);var g=m(function(e,t){var n=e.innerRef,r=e.navigate,a=e.onClick,i=(0,s.A)(e,["innerRef","navigate","onClick"]),c=i.target,u=(0,l.A)({},i,{onClick:function(e){try{a&&a(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||c&&"_self"!==c||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),r())}});return u.ref=h!==m&&t||n,o.createElement("a",u)});var b=m(function(e,t){var n=e.component,a=void 0===n?g:n,u=e.replace,d=e.to,b=e.innerRef,y=(0,s.A)(e,["component","replace","to","innerRef"]);return o.createElement(r.XZ.Consumer,null,function(e){e||(0,c.A)(!1);var n=e.history,r=p(f(d,e.location),e.location),s=r?n.createHref(r):"",g=(0,l.A)({},y,{href:s,navigate:function(){var t=f(d,e.location),r=(0,i.AO)(e.location)===(0,i.AO)(p(t));(u||r?n.replace:n.push)(t)}});return h!==m?g.ref=t||b:g.innerRef=b,o.createElement(a,g)})}),y=function(e){return e},v=o.forwardRef;void 0===v&&(v=y);var w=v(function(e,t){var n=e["aria-current"],a=void 0===n?"page":n,i=e.activeClassName,u=void 0===i?"active":i,d=e.activeStyle,h=e.className,m=e.exact,g=e.isActive,w=e.location,k=e.sensitive,S=e.strict,x=e.style,_=e.to,E=e.innerRef,C=(0,s.A)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return o.createElement(r.XZ.Consumer,null,function(e){e||(0,c.A)(!1);var n=w||e.location,i=p(f(_,n),n),s=i.pathname,A=s&&s.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),L=A?(0,r.B6)(n.pathname,{path:A,exact:m,sensitive:k,strict:S}):null,T=!!(g?g(L,n):L),j="function"==typeof h?h(T):h,P="function"==typeof x?x(T):x;T&&(j=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter(function(e){return e}).join(" ")}(j,u),P=(0,l.A)({},P,d));var M=(0,l.A)({"aria-current":T&&a||null,className:j,style:P,to:i},C);return y!==v?M.ref=t||E:M.innerRef=E,o.createElement(b,M)})})},4634:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},4784:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={title:"BharatMLStack",tagline:"BharatMLStack is a comprehensive, production-ready machine learning infrastructure platform designed to democratize ML capabilities across India and beyond. Our mission is to provide a robust, scalable, and accessible ML stack that empowers organizations to build, deploy, and manage machine learning solutions at massive scale.",favicon:"img/favicon.ico",future:{v4:{removeLegacyPostBuildHeadAttribute:!0,useCssCascadeLayers:!0},experimental_faster:{swcJsLoader:!1,swcJsMinimizer:!1,swcHtmlMinimizer:!1,lightningCssMinimizer:!1,mdxCrossCompilerCache:!1,rspackBundler:!1,rspackPersistentCache:!1,ssgWorkerThreads:!1},experimental_storage:{type:"localStorage",namespace:!1},experimental_router:"browser"},url:"https://meesho.github.io",baseUrl:"/BharatMLStack/",organizationName:"Meesho Ltd.",projectName:"BharatMLStack",onBrokenLinks:"throw",onBrokenMarkdownLinks:"warn",i18n:{defaultLocale:"en",locales:["en"],path:"i18n",localeConfigs:{}},presets:[["classic",{docs:{sidebarPath:"./sidebars.js",editUrl:"https://github.com/Meesho/BharatMLStack/tree/main/docs",routeBasePath:"/"},blog:{showReadingTime:!0,feedOptions:{type:["rss","atom"],xslt:!0},editUrl:"https://github.com/Meesho/BharatMLStack/tree/main/docs",onInlineTags:"warn",onInlineAuthors:"warn",onUntruncatedBlogPosts:"warn"},theme:{customCss:"./src/css/custom.css"}}]],themeConfig:{image:"img/docusaurus-social-card.jpg",navbar:{title:"BharatMLStack",items:[{type:"docSidebar",sidebarId:"tutorialSidebar",position:"left",label:"Docs"},{to:"/blog",label:"Blog",position:"left"},{href:"https://github.com/Meesho/BharatMLStack",label:"GitHub",position:"right"}],hideOnScroll:!1},footer:{style:"dark",links:[{title:"Community",items:[{label:"Github Discussions",href:"https://github.com/Meesho/BharatMLStack/discussions"},{label:"Discord",href:"https://discord.gg/XkT7XsV2AU"}]},{title:"More",items:[{label:"Blog",to:"/blog"},{label:"GitHub",href:"https://github.com/Meesho/BharatMLStack"}]}],copyright:"Copyright \xa9 2026 Meesho Ltd. Built with Docusaurus."},prism:{theme:{plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:[],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},colorMode:{defaultMode:"light",disableSwitch:!1,respectPrefersColorScheme:!1},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},blog:{sidebar:{groupByYear:!0}},metadata:[],tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3}},baseUrlIssueBanner:!0,onBrokenAnchors:"warn",onDuplicateRoutes:"warn",staticDirectories:["static"],customFields:{},plugins:[],themes:[],scripts:[],headTags:[],stylesheets:[],clientModules:[],titleDelimiter:"|",noIndex:!1,markdown:{format:"mdx",mermaid:!1,mdx1Compat:{comments:!0,admonitions:!0,headingIds:!0},anchors:{maintainCase:!1}}}},4848:(e,t,n)=>{"use strict";e.exports=n(9698)},5041:(e,t,n)=>{"use strict";n.d(t,{M:()=>m,o:()=>h});var r=n(6540),a=n(2303),o=n(679),i=n(9532),l=n(6342),s=n(4848);const c=(0,o.Wf)("docusaurus.announcement.dismiss"),u=(0,o.Wf)("docusaurus.announcement.id"),d=()=>"true"===c.get(),f=e=>c.set(String(e)),p=r.createContext(null);function h({children:e}){const t=function(){const{announcementBar:e}=(0,l.p)(),t=(0,a.A)(),[n,o]=(0,r.useState)(()=>!!t&&d());(0,r.useEffect)(()=>{o(d())},[]);const i=(0,r.useCallback)(()=>{f(!0),o(!0)},[]);return(0,r.useEffect)(()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&f(!1),!r&&d()||o(!1)},[e]),(0,r.useMemo)(()=>({isActive:!!e&&!n,close:i}),[e,n,i])}();return(0,s.jsx)(p.Provider,{value:t,children:e})}function m(){const e=(0,r.useContext)(p);if(!e)throw new i.dV("AnnouncementBarProvider");return e}},5062:(e,t,n)=>{"use strict";n.d(t,{$:()=>i});var r=n(6540),a=n(6347),o=n(9532);function i(e){const t=(0,a.zy)(),n=(0,o.ZC)(t),i=(0,o._q)(e);(0,r.useEffect)(()=>{n&&t!==n&&i({location:t,previousLocation:n})},[i,t,n])}},5260:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});n(6540);var r=n(545),a=n(4848);function o(e){return(0,a.jsx)(r.mg,{...e})}},5293:(e,t,n)=>{"use strict";n.d(t,{G:()=>w,a:()=>v});var r=n(6540),a=n(9532),o=n(679),i=n(6342),l=n(4848);function s(){return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function c(e){return function(e,t){const n=window.matchMedia(e);return n.addEventListener("change",t),()=>n.removeEventListener("change",t)}("(prefers-color-scheme: dark)",()=>e(s()))}const u=r.createContext(void 0),d=(0,o.Wf)("theme"),f="system",p=e=>"dark"===e?"dark":"light",h=e=>null===e||e===f?null:p(e),m={get:()=>p(document.documentElement.getAttribute("data-theme")),set:e=>{document.documentElement.setAttribute("data-theme",p(e))}},g={get:()=>h(document.documentElement.getAttribute("data-theme-choice")),set:e=>{document.documentElement.setAttribute("data-theme-choice",h(e)??f)}},b=e=>{null===e?d.del():d.set(p(e))};function y(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,i.p)(),{colorMode:a,setColorModeState:o,colorModeChoice:l,setColorModeChoiceState:u}=function(){const{colorMode:{defaultMode:e}}=(0,i.p)(),[t,n]=(0,r.useState)(e),[a,o]=(0,r.useState)(null);return(0,r.useEffect)(()=>{n(m.get()),o(g.get())},[]),{colorMode:t,setColorModeState:n,colorModeChoice:a,setColorModeChoiceState:o}}();(0,r.useEffect)(()=>{t&&d.del()},[t]);const f=(0,r.useCallback)((t,r={})=>{const{persist:a=!0}=r;if(null===t){const t=n?s():e;m.set(t),o(t),g.set(null),u(null)}else m.set(t),g.set(t),o(t),u(t);a&&b(t)},[o,u,n,e]);return(0,r.useEffect)(()=>d.listen(e=>{f(h(e.newValue))}),[f]),(0,r.useEffect)(()=>{if(null===l&&n)return c(e=>{o(e),m.set(e)})},[n,l,o]),(0,r.useMemo)(()=>({colorMode:a,colorModeChoice:l,setColorMode:f,get isDarkTheme(){return"dark"===a},setLightTheme(){f("light")},setDarkTheme(){f("dark")}}),[a,l,f])}function v({children:e}){const t=y();return(0,l.jsx)(u.Provider,{value:t,children:e})}function w(){const e=(0,r.useContext)(u);if(null==e)throw new a.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},5338:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(1247)},5500:(e,t,n)=>{"use strict";n.d(t,{Jx:()=>b,be:()=>h,e3:()=>g});var r=n(6540),a=n(4164),o=n(5260),i=n(6803),l=n(6025),s=n(4563),c=n(4848);function u({title:e}){const t=(0,s.s$)().format(e);return(0,c.jsxs)(o.A,{children:[(0,c.jsx)("title",{children:t}),(0,c.jsx)("meta",{property:"og:title",content:t})]})}function d({description:e}){return(0,c.jsxs)(o.A,{children:[(0,c.jsx)("meta",{name:"description",content:e}),(0,c.jsx)("meta",{property:"og:description",content:e})]})}function f({image:e}){const{withBaseUrl:t}=(0,l.hH)(),n=t(e,{absolute:!0});return(0,c.jsxs)(o.A,{children:[(0,c.jsx)("meta",{property:"og:image",content:n}),(0,c.jsx)("meta",{name:"twitter:image",content:n})]})}function p({keywords:e}){return(0,c.jsx)(o.A,{children:(0,c.jsx)("meta",{name:"keywords",content:Array.isArray(e)?e.join(","):e})})}function h({title:e,description:t,keywords:n,image:r,children:a}){return(0,c.jsxs)(c.Fragment,{children:[e&&(0,c.jsx)(u,{title:e}),t&&(0,c.jsx)(d,{description:t}),n&&(0,c.jsx)(p,{keywords:n}),r&&(0,c.jsx)(f,{image:r}),a&&(0,c.jsx)(o.A,{children:a})]})}const m=r.createContext(void 0);function g({className:e,children:t}){const n=r.useContext(m),i=(0,a.A)(n,e);return(0,c.jsxs)(m.Provider,{value:i,children:[(0,c.jsx)(o.A,{children:(0,c.jsx)("html",{className:i})}),t]})}function b({children:e}){const t=(0,i.A)(),n=`plugin-${t.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const r=`plugin-id-${t.plugin.id}`;return(0,c.jsx)(g,{className:(0,a.A)(n,r),children:e})}},5556:(e,t,n)=>{e.exports=n(2694)()},5600:(e,t,n)=>{"use strict";n.d(t,{GX:()=>c,YL:()=>s,y_:()=>l});var r=n(6540),a=n(9532),o=n(4848);const i=r.createContext(null);function l({children:e}){const t=(0,r.useState)({component:null,props:null});return(0,o.jsx)(i.Provider,{value:t,children:e})}function s(){const e=(0,r.useContext)(i);if(!e)throw new a.dV("NavbarSecondaryMenuContentProvider");return e[0]}function c({component:e,props:t}){const n=(0,r.useContext)(i);if(!n)throw new a.dV("NavbarSecondaryMenuContentProvider");const[,o]=n,l=(0,a.Be)(t);return(0,r.useEffect)(()=>{o({component:e,props:l})},[o,e,l]),(0,r.useEffect)(()=>()=>o({component:null,props:null}),[o]),null}},5947:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function a(e,t,n){return e<t?t:e>n?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(r.barSelector),u=r.speed,d=r.easing;return o.offsetWidth,l(function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(c,i(e,u,d)),1===e?(s(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout(function(){s(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout(function(){n.remove(),t()},u)},u)):setTimeout(t,u)}),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout(function(){n.status&&(n.trickle(),e())},r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always(function(){0===--t?(e=0,n.done()):n.set((e-t)/e)}),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),c=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&p(a),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(e,t){return t.toUpperCase()})}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function c(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=f(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},6025:(e,t,n)=>{"use strict";n.d(t,{Ay:()=>l,hH:()=>i});var r=n(6540),a=n(4586),o=n(6654);function i(){const{siteConfig:e}=(0,a.A)(),{baseUrl:t,url:n}=e,i=e.future.experimental_router,l=(0,r.useCallback)((e,r)=>function({siteUrl:e,baseUrl:t,url:n,options:{forcePrependBaseUrl:r=!1,absolute:a=!1}={},router:i}){if(!n||n.startsWith("#")||(0,o.z)(n))return n;if("hash"===i)return n.startsWith("/")?`.${n}`:`./${n}`;if(r)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const l=n.startsWith(t)?n:t+n.replace(/^\//,"");return a?e+l:l}({siteUrl:n,baseUrl:t,url:e,options:r,router:i}),[n,t,i]);return{withBaseUrl:l}}function l(e,t={}){const{withBaseUrl:n}=i();return n(e,t)}},6125:(e,t,n)=>{"use strict";n.d(t,{o:()=>o,x:()=>i});var r=n(6540),a=n(4848);const o=r.createContext(!1);function i({children:e}){const[t,n]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{n(!0)},[]),(0,a.jsx)(o.Provider,{value:t,children:e})}},6134:(e,t,n)=>{"use strict";var r=n(1765),a=n(4784);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t,o=globalThis.Prism;globalThis.Prism=e,r.forEach(e=>{"php"===e&&n(9700),n(8692)(`./prism-${e}`)}),delete globalThis.Prism,void 0!==o&&(globalThis.Prism=e)}(r.My)},6221:(e,t,n)=>{"use strict";var r=n(6540);function a(e){var t="https://react.dev/errors/"+e;if(1<arguments.length){t+="?args[]="+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n])}return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}function o(){}var i={d:{f:o,r:function(){throw Error(a(522))},D:o,C:o,L:o,m:o,X:o,S:o,M:o},p:0,findDOMNode:null},l=Symbol.for("react.portal");var s=r.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function c(e,t){return"font"===e?"":"string"==typeof t?"use-credentials"===t?t:"":void 0}t.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=i,t.createPortal=function(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!t||1!==t.nodeType&&9!==t.nodeType&&11!==t.nodeType)throw Error(a(299));return function(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:l,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}(e,t,null,n)},t.flushSync=function(e){var t=s.T,n=i.p;try{if(s.T=null,i.p=2,e)return e()}finally{s.T=t,i.p=n,i.d.f()}},t.preconnect=function(e,t){"string"==typeof e&&(t?t="string"==typeof(t=t.crossOrigin)?"use-credentials"===t?t:"":void 0:t=null,i.d.C(e,t))},t.prefetchDNS=function(e){"string"==typeof e&&i.d.D(e)},t.preinit=function(e,t){if("string"==typeof e&&t&&"string"==typeof t.as){var n=t.as,r=c(n,t.crossOrigin),a="string"==typeof t.integrity?t.integrity:void 0,o="string"==typeof t.fetchPriority?t.fetchPriority:void 0;"style"===n?i.d.S(e,"string"==typeof t.precedence?t.precedence:void 0,{crossOrigin:r,integrity:a,fetchPriority:o}):"script"===n&&i.d.X(e,{crossOrigin:r,integrity:a,fetchPriority:o,nonce:"string"==typeof t.nonce?t.nonce:void 0})}},t.preinitModule=function(e,t){if("string"==typeof e)if("object"==typeof t&&null!==t){if(null==t.as||"script"===t.as){var n=c(t.as,t.crossOrigin);i.d.M(e,{crossOrigin:n,integrity:"string"==typeof t.integrity?t.integrity:void 0,nonce:"string"==typeof t.nonce?t.nonce:void 0})}}else null==t&&i.d.M(e)},t.preload=function(e,t){if("string"==typeof e&&"object"==typeof t&&null!==t&&"string"==typeof t.as){var n=t.as,r=c(n,t.crossOrigin);i.d.L(e,n,{crossOrigin:r,integrity:"string"==typeof t.integrity?t.integrity:void 0,nonce:"string"==typeof t.nonce?t.nonce:void 0,type:"string"==typeof t.type?t.type:void 0,fetchPriority:"string"==typeof t.fetchPriority?t.fetchPriority:void 0,referrerPolicy:"string"==typeof t.referrerPolicy?t.referrerPolicy:void 0,imageSrcSet:"string"==typeof t.imageSrcSet?t.imageSrcSet:void 0,imageSizes:"string"==typeof t.imageSizes?t.imageSizes:void 0,media:"string"==typeof t.media?t.media:void 0})}},t.preloadModule=function(e,t){if("string"==typeof e)if(t){var n=c(t.as,t.crossOrigin);i.d.m(e,{as:"string"==typeof t.as&&"script"!==t.as?t.as:void 0,crossOrigin:n,integrity:"string"==typeof t.integrity?t.integrity:void 0})}else i.d.m(e)},t.requestFormReset=function(e){i.d.r(e)},t.unstable_batchedUpdates=function(e,t){return e(t)},t.useFormState=function(e,t,n){return s.H.useFormState(e,t,n)},t.useFormStatus=function(){return s.H.useHostTransitionStatus()},t.version="19.1.1"},6294:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(5947),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate({location:e,previousLocation:t}){if(t&&e.pathname!==t.pathname){const e=window.setTimeout(()=>{a().start()},200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},6342:(e,t,n)=>{"use strict";n.d(t,{p:()=>a});var r=n(4586);function a(){return(0,r.A)().siteConfig.themeConfig}},6347:(e,t,n)=>{"use strict";n.d(t,{B6:()=>x,Ix:()=>v,W6:()=>M,XZ:()=>y,dO:()=>j,qh:()=>_,zy:()=>N});var r=n(2892),a=n(6540),o=n(5556),i=n.n(o),l=n(1513),s=n(1561),c=n(8168),u=n(8505),d=n.n(u),f=(n(4363),n(8587)),p=(n(4146),1073741823),h="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};var m=a.createContext||function(e,t){var n,o,l="__create-react-context-"+function(){var e="__global_unique_id__";return h[e]=(h[e]||0)+1}()+"__",s=function(e){function n(){for(var t,n,r,a=arguments.length,o=new Array(a),i=0;i<a;i++)o[i]=arguments[i];return(t=e.call.apply(e,[this].concat(o))||this).emitter=(n=t.props.value,r=[],{on:function(e){r.push(e)},off:function(e){r=r.filter(function(t){return t!==e})},get:function(){return n},set:function(e,t){n=e,r.forEach(function(e){return e(n,t)})}}),t}(0,r.A)(n,e);var a=n.prototype;return a.getChildContext=function(){var e;return(e={})[l]=this.emitter,e},a.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,a=e.value;((o=r)===(i=a)?0!==o||1/o==1/i:o!=o&&i!=i)?n=0:(n="function"==typeof t?t(r,a):p,0!==(n|=0)&&this.emitter.set(e.value,n))}var o,i},a.render=function(){return this.props.children},n}(a.Component);s.childContextTypes=((n={})[l]=i().object.isRequired,n);var c=function(t){function n(){for(var e,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(e=t.call.apply(t,[this].concat(r))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){0!==((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}(0,r.A)(n,t);var a=n.prototype;return a.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?p:t},a.componentDidMount=function(){this.context[l]&&this.context[l].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?p:e},a.componentWillUnmount=function(){this.context[l]&&this.context[l].off(this.onUpdate)},a.getValue=function(){return this.context[l]?this.context[l].get():e},a.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(a.Component);return c.contextTypes=((o={})[l]=i().object,o),{Provider:s,Consumer:c}},g=function(e){var t=m();return t.displayName=e,t},b=g("Router-History"),y=g("Router"),v=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen(function(e){n._pendingLocation=e})),n}(0,r.A)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen(function(t){e._isMounted&&e.setState({location:t})})),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return a.createElement(y.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},a.createElement(b.Provider,{children:this.props.children||null,value:this.props.history}))},t}(a.Component);a.Component;a.Component;var w={},k=1e4,S=0;function x(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,a=n.exact,o=void 0!==a&&a,i=n.strict,l=void 0!==i&&i,s=n.sensitive,c=void 0!==s&&s;return[].concat(r).reduce(function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=w[n]||(w[n]={});if(r[e])return r[e];var a=[],o={regexp:d()(e,a,t),keys:a};return S<k&&(r[e]=o,S++),o}(n,{end:o,strict:l,sensitive:c}),a=r.regexp,i=r.keys,s=a.exec(e);if(!s)return null;var u=s[0],f=s.slice(1),p=e===u;return o&&!p?null:{path:n,url:"/"===n&&""===u?"/":u,isExact:p,params:i.reduce(function(e,t,n){return e[t.name]=f[n],e},{})}},null)}var _=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.A)(t,e),t.prototype.render=function(){var e=this;return a.createElement(y.Consumer,null,function(t){t||(0,s.A)(!1);var n=e.props.location||t.location,r=e.props.computedMatch?e.props.computedMatch:e.props.path?x(n.pathname,e.props):t.match,o=(0,c.A)({},t,{location:n,match:r}),i=e.props,l=i.children,u=i.component,d=i.render;return Array.isArray(l)&&function(e){return 0===a.Children.count(e)}(l)&&(l=null),a.createElement(y.Provider,{value:o},o.match?l?"function"==typeof l?l(o):l:u?a.createElement(u,o):d?d(o):null:"function"==typeof l?l(o):null)})},t}(a.Component);function E(e){return"/"===e.charAt(0)?e:"/"+e}function C(e,t){if(!e)return t;var n=E(e);return 0!==t.pathname.indexOf(n)?t:(0,c.A)({},t,{pathname:t.pathname.substr(n.length)})}function A(e){return"string"==typeof e?e:(0,l.AO)(e)}function L(e){return function(){(0,s.A)(!1)}}function T(){}a.Component;var j=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.A)(t,e),t.prototype.render=function(){var e=this;return a.createElement(y.Consumer,null,function(t){t||(0,s.A)(!1);var n,r,o=e.props.location||t.location;return a.Children.forEach(e.props.children,function(e){if(null==r&&a.isValidElement(e)){n=e;var i=e.props.path||e.props.from;r=i?x(o.pathname,(0,c.A)({},e.props,{path:i})):t.match}}),r?a.cloneElement(n,{location:o,computedMatch:r}):null})},t}(a.Component);var P=a.useContext;function M(){return P(b)}function N(){return P(y).location}},6540:(e,t,n)=>{"use strict";e.exports=n(9869)},6654:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{A:()=>a,z:()=>r})},6803:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(3102);function o(){const e=r.useContext(a.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}},6921:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach(([n,o])=>{const i=a?`${a}.${n}`:n;r(o)?e(o,i):t[i]=o})}(e),t}},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},6969:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to <a href="https://webplatform.github.io/docs/">WebPlatform.org documentation</a>. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (<code>.comment</code> can become <code>.namespace--comment</code>) or replace them with your defined ones (like <code>.editor__comment</code>). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the <code>highlightAll</code> and <code>highlightAllUnder</code> methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},6972:(e,t,n)=>{"use strict";n.d(t,{$S:()=>h,B5:()=>C,Nr:()=>p,OF:()=>S,QB:()=>E,Vd:()=>x,Y:()=>w,a4:()=>m,cC:()=>f,d1:()=>A,fW:()=>_,w8:()=>y});var r=n(6540),a=n(6347),o=n(2831),i=n(4070),l=n(9169),s=n(1682),c=n(3886),u=n(3025),d=n(609);function f(e){const t=(0,u.r)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function p(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=p(t);if(e)return e}}(e):void 0:e.href}function h(){const{pathname:e}=(0,a.zy)(),t=(0,d.t)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=k({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}function m(){const{pathname:e}=(0,a.zy)(),t=(0,d.t)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=k({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];return n?.items??t.items}const g=(e,t)=>void 0!==e&&(0,l.ys)(e,t),b=(e,t)=>e.some(e=>y(e,t));function y(e,t){return"link"===e.type?g(e.href,t):"category"===e.type&&(g(e.href,t)||b(e.items,t))}function v(e,t){switch(e.type){case"category":return y(e,t)||void 0!==e.href&&!e.linkUnlisted||e.items.some(e=>v(e,t));case"link":return!e.unlisted||y(e,t);default:return!0}}function w(e,t){return(0,r.useMemo)(()=>e.filter(e=>v(e,t)),[e,t])}function k({sidebarItems:e,pathname:t,onlyCategories:n=!1}){const r=[];return function e(a){for(const o of a)if("category"===o.type&&((0,l.ys)(o.href,t)||e(o.items))||"link"===o.type&&(0,l.ys)(o.href,t)){return n&&"category"!==o.type||r.unshift(o),!0}return!1}(e),r}function S(){const e=(0,d.t)(),{pathname:t}=(0,a.zy)(),n=(0,i.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?k({sidebarItems:e.items,pathname:t}):null}function x(e){const{activeVersion:t}=(0,i.zK)(e),{preferredVersion:n}=(0,c.g1)(e),a=(0,i.r7)(e);return(0,r.useMemo)(()=>(0,s.sb)([t,n,a].filter(Boolean)),[t,n,a])}function _(e,t){const n=x(t);return(0,r.useMemo)(()=>{const t=n.flatMap(e=>e.sidebars?Object.entries(e.sidebars):[]),r=t.find(t=>t[0]===e);if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map(e=>e.name).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map(e=>e[0]).join("\n- ")}`);return r[1]},[e,n])}function E(e,t){const n=x(t);return(0,r.useMemo)(()=>{const t=n.flatMap(e=>e.docs),r=t.find(t=>t.id===e);if(!r){if(n.flatMap(e=>e.draftIds).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map(e=>e.name).join(", ")}".\nAvailable doc ids are:\n- ${(0,s.sb)(t.map(e=>e.id)).join("\n- ")}`)}return r},[e,n])}function C({route:e}){const t=(0,a.zy)(),n=(0,u.r)(),r=e.routes,i=r.find(e=>(0,a.B6)(t.pathname,e));if(!i)return null;const l=i.sidebar,s=l?n.docsSidebars[l]:void 0;return{docElement:(0,o.v)(r),sidebarName:l,sidebarItems:s}}function A(e){return e.filter(e=>!("category"===e.type||"link"===e.type)||!!p(e))}},6988:(e,t,n)=>{"use strict";n.d(t,{o:()=>d,l:()=>f});var r=n(6540),a=n(4784);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/BharatMLStack/","versions":[{"name":"current","label":"Next","isLast":true,"path":"/BharatMLStack/","mainDocId":"online-feature-store/v1.0.0/architecture","docs":[{"id":"inferflow/v1.0.0/architecture","path":"/BharatMLStack/inferflow/v1.0.0/architecture","sidebar":"tutorialSidebar"},{"id":"inferflow/v1.0.0/configuration","path":"/BharatMLStack/inferflow/v1.0.0/configuration","sidebar":"tutorialSidebar"},{"id":"inferflow/v1.0.0/functionalities","path":"/BharatMLStack/inferflow/v1.0.0/functionalities","sidebar":"tutorialSidebar"},{"id":"inferflow/v1.0.0/release-notes","path":"/BharatMLStack/inferflow/v1.0.0/release-notes","sidebar":"tutorialSidebar"},{"id":"numerix/v1.0.0/architecture","path":"/BharatMLStack/numerix/v1.0.0/architecture","sidebar":"tutorialSidebar"},{"id":"numerix/v1.0.0/benchmarks","path":"/BharatMLStack/numerix/v1.0.0/benchmarks","sidebar":"tutorialSidebar"},{"id":"numerix/v1.0.0/functionalities","path":"/BharatMLStack/numerix/v1.0.0/functionalities","sidebar":"tutorialSidebar"},{"id":"numerix/v1.0.0/release-notes","path":"/BharatMLStack/numerix/v1.0.0/release-notes","sidebar":"tutorialSidebar"},{"id":"online-feature-store/v1.0.0/architecture","path":"/BharatMLStack/online-feature-store/v1.0.0/architecture","sidebar":"tutorialSidebar"},{"id":"online-feature-store/v1.0.0/benchmarks","path":"/BharatMLStack/online-feature-store/v1.0.0/benchmarks","sidebar":"tutorialSidebar"},{"id":"online-feature-store/v1.0.0/data-formats","path":"/BharatMLStack/online-feature-store/v1.0.0/data-formats","sidebar":"tutorialSidebar"},{"id":"online-feature-store/v1.0.0/functionalities","path":"/BharatMLStack/online-feature-store/v1.0.0/functionalities","sidebar":"tutorialSidebar"},{"id":"online-feature-store/v1.0.0/release-notes","path":"/BharatMLStack/online-feature-store/v1.0.0/release-notes","sidebar":"tutorialSidebar"},{"id":"quick-start/v1.0.0/quick-start","path":"/BharatMLStack/quick-start/v1.0.0/quick-start","sidebar":"tutorialSidebar"},{"id":"sdks/go/v1.0.0/feature_client","path":"/BharatMLStack/sdks/go/v1.0.0/feature_client","sidebar":"tutorialSidebar"},{"id":"sdks/python/v1.0.0/grpc_feature_client","path":"/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client","sidebar":"tutorialSidebar"},{"id":"sdks/python/v1.0.0/spark_feature_push_client","path":"/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client","sidebar":"tutorialSidebar"},{"id":"trufflebox-ui/v1.0.0/userguide","path":"/BharatMLStack/trufflebox-ui/v1.0.0/userguide","sidebar":"tutorialSidebar"},{"id":"/category/online-feature-store","path":"/BharatMLStack/category/online-feature-store","sidebar":"tutorialSidebar"},{"id":"/online-feature-store/v1.0.0","path":"/BharatMLStack/online-feature-store/v1.0.0","sidebar":"tutorialSidebar"},{"id":"/category/inferflow","path":"/BharatMLStack/category/inferflow","sidebar":"tutorialSidebar"},{"id":"/inferflow/v1.0.0","path":"/BharatMLStack/inferflow/v1.0.0","sidebar":"tutorialSidebar"},{"id":"/category/quick-start","path":"/BharatMLStack/category/quick-start","sidebar":"tutorialSidebar"},{"id":"/category/trufflebox-ui","path":"/BharatMLStack/category/trufflebox-ui","sidebar":"tutorialSidebar"},{"id":"/category/sdks","path":"/BharatMLStack/category/sdks","sidebar":"tutorialSidebar"},{"id":"/category/go-sdk","path":"/BharatMLStack/category/go-sdk","sidebar":"tutorialSidebar"},{"id":"/category/python-sdk","path":"/BharatMLStack/category/python-sdk","sidebar":"tutorialSidebar"},{"id":"/category/v100","path":"/BharatMLStack/category/v100","sidebar":"tutorialSidebar"},{"id":"/category/numerix","path":"/BharatMLStack/category/numerix","sidebar":"tutorialSidebar"},{"id":"/numerix/v1.0.0","path":"/BharatMLStack/numerix/v1.0.0","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/BharatMLStack/category/online-feature-store","label":"Online Feature Store"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var l=n(2654);const s=JSON.parse('{"docusaurusVersion":"3.8.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-css-cascade-layers":{"type":"package","name":"@docusaurus/plugin-css-cascade-layers","version":"3.8.1"},"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.8.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.8.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.8.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.8.1"},"docusaurus-plugin-svgr":{"type":"package","name":"@docusaurus/plugin-svgr","version":"3.8.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.8.1"}}}');var c=n(4848);const u={siteConfig:a.default,siteMetadata:s,globalData:o,i18n:i,codeTranslations:l},d=r.createContext(u);function f({children:e}){return(0,c.jsx)(d.Provider,{value:u,children:e})}},7065:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});const r="default"},7489:(e,t,n)=>{"use strict";n.d(t,{A:()=>m});var r=n(6540),a=n(8193),o=n(5260),i=n(440),l=n(1656),s=n(3102),c=n(4848);function u({error:e,tryAgain:t}){return(0,c.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,c.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,c.jsx)("button",{type:"button",onClick:t,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,c.jsx)(d,{error:e})]})}function d({error:e}){const t=(0,i.rA)(e).map(e=>e.message).join("\n\nCause:\n");return(0,c.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:t})}function f({children:e}){return(0,c.jsx)(s.W,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:e})}function p({error:e,tryAgain:t}){return(0,c.jsx)(f,{children:(0,c.jsxs)(m,{fallback:()=>(0,c.jsx)(u,{error:e,tryAgain:t}),children:[(0,c.jsx)(o.A,{children:(0,c.jsx)("title",{children:"Page Error"})}),(0,c.jsx)(l.A,{children:(0,c.jsx)(u,{error:e,tryAgain:t})})]})})}const h=e=>(0,c.jsx)(p,{...e});class m extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.A.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??h)(e)}return e??null}}},7559:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",blogAuthorsListPage:"blog-authors-list-page",blogAuthorsPostsPage:"blog-authors-posts-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",draftBanner:"theme-draft-banner",admonitionType:e=>`theme-admonition-${e}`},announcementBar:{container:"theme-announcement-bar"},layout:{navbar:{container:"theme-layout-navbar",containerLeft:"theme-layout-navbar-left",containerRight:"theme-layout-navbar-right",mobileSidebar:{container:"theme-layout-navbar-sidebar",panel:"theme-layout-navbar-sidebar-panel"}},main:{container:"theme-layout-main"},footer:{container:"theme-layout-footer",column:"theme-layout-footer-column"}},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"},pages:{pageFooterEditMetaRow:"theme-pages-footer-edit-meta-row"}}},8168:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(null,arguments)}n.d(t,{A:()=>r})},8193:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},8328:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});n(6540);var r=n(3259),a=n.n(r),o=n(4054);const i={"00b12b9c":[()=>n.e(7048).then(n.bind(n,8517)),"@site/blog/bharatmlstack-history/post-two/index.md",8517],"01a85c17":[()=>Promise.all([n.e(1869),n.e(8209)]).then(n.bind(n,9158)),"@theme/BlogTagsListPage",9158],"0413d9af":[()=>n.e(9919).then(n.bind(n,7114)),"@site/docs/sdks/python/v1.0.0/grpc_feature_client.md",7114],"08daf6b6":[()=>n.e(1686).then(n.t.bind(n,848,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-model-inference-44e.json",848],"09dd5be9":[()=>n.e(6273).then(n.bind(n,8831)),"@site/blog/bharatmlstack-history/post-one/index.md",8831],"0a89f5c9":[()=>n.e(7508).then(n.bind(n,5641)),"@site/docs/inferflow/v1.0.0/functionalities.md",5641],"0fff8dc8":[()=>n.e(9596).then(n.bind(n,5958)),"@site/docs/quick-start/v1.0.0/quick-start.md",5958],14064408:[()=>n.e(4582).then(n.t.bind(n,9416,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-quick-start-b0e.json",9416],"14eb3368":[()=>Promise.all([n.e(1869),n.e(6969)]).then(n.bind(n,477)),"@theme/DocCategoryGeneratedIndexPage",477],"176d210f":[()=>n.e(6100).then(n.bind(n,753)),"@site/docs/trufflebox-ui/v1.0.0/userguide.md",753],17896441:[()=>Promise.all([n.e(1869),n.e(6870),n.e(8401)]).then(n.bind(n,833)),"@theme/DocItem",833],"1a64de69":[()=>n.e(3645).then(n.t.bind(n,1694,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-meesho-214.json",1694],"1f391b9e":[()=>Promise.all([n.e(1869),n.e(6870),n.e(6061)]).then(n.bind(n,7973)),"@theme/MDXPage",7973],"252a9097":[()=>n.e(4424).then(n.bind(n,248)),"@site/docs/inferflow/v1.0.0/architecture.md",248],"2c62ead1":[()=>n.e(5801).then(n.bind(n,1688)),"@site/docs/numerix/v1.0.0/functionalities.md",1688],"2d865531":[()=>n.e(9197).then(n.t.bind(n,4153,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-authors-eb6.json",4153],"3216e812":[()=>n.e(4771).then(n.t.bind(n,1494,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-numerix-v-1-0-0-85d.json",1494],"36994c47":[()=>n.e(9858).then(n.t.bind(n,5516,19)),"@generated/docusaurus-plugin-content-blog/default/__plugin.json",5516],"393be207":[()=>n.e(4134).then(n.bind(n,591)),"@site/src/pages/markdown-page.md",591],"3980073a":[()=>n.e(940).then(n.t.bind(n,3840,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-interaction-store-62d.json",3840],"3aeb33c7":[()=>n.e(974).then(n.bind(n,7309)),"@site/blog/bharatmlstack-history/post-five/index.md",7309],"3e1c5046":[()=>n.e(690).then(n.t.bind(n,8750,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-online-feature-store-e01.json",8750],"4137b431":[()=>n.e(6054).then(n.t.bind(n,4019,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-aad.json",4019],"428aafcc":[()=>n.e(5503).then(n.bind(n,7999)),"@site/blog/bharatmlstack-history/post-three/index.md",7999],"44d1c015":[()=>n.e(1065).then(n.t.bind(n,6725,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-python-sdk-f96.json",6725],"45a03d07":[()=>n.e(9955).then(n.t.bind(n,8539,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-inferflow-v-1-0-0-705.json",8539],"479eb034":[()=>n.e(5425).then(n.t.bind(n,9341,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-mlplatform-b63.json",9341],"4af50aac":[()=>n.e(1964).then(n.bind(n,6220)),"@site/docs/sdks/go/v1.0.0/feature_client.md",6220],"4caa95bf":[()=>n.e(2344).then(n.bind(n,9584)),"@site/docs/online-feature-store/v1.0.0/data-formats.md",9584],"4df0e30b":[()=>n.e(2379).then(n.bind(n,9680)),"@site/docs/numerix/v1.0.0/architecture.md",9680],"50899a24":[()=>n.e(1009).then(n.t.bind(n,1008,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-numerix-843.json",1008],"5e95c892":[()=>n.e(9647).then(n.bind(n,7121)),"@theme/DocsRoot",7121],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,4784)),"@generated/docusaurus.config",4784],"616111d3":[()=>n.e(9158).then(n.t.bind(n,9470,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-sdks-291.json",9470],"621db11d":[()=>Promise.all([n.e(1869),n.e(7518),n.e(4212)]).then(n.bind(n,3250)),"@theme/Blog/Pages/BlogAuthorsListPage",3250],"6479fb86":[()=>n.e(5579).then(n.t.bind(n,3751,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-archive-553.json",3751],"67d4782a":[()=>n.e(8588).then(n.bind(n,8769)),"@site/docs/online-feature-store/v1.0.0/benchmarks.md",8769],"6875c492":[()=>Promise.all([n.e(1869),n.e(6870),n.e(7518),n.e(4813)]).then(n.bind(n,3069)),"@theme/BlogTagsPostsPage",3069],"6bb91276":[()=>n.e(9226).then(n.t.bind(n,8758,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-vllm-9b4.json",8758],"72dc5b25":[()=>n.e(8261).then(n.t.bind(n,3613,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-online-feature-store-v-1-0-0-a94.json",3613],"79ae4ea7":[()=>n.e(4340).then(n.bind(n,4311)),"@site/blog/bharatmlstack-history/post-four/index.md",4311],"7fa80e1c":[()=>n.e(3322).then(n.t.bind(n,9189,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-853.json",9189],"814f3328":[()=>n.e(7472).then(n.t.bind(n,5513,19)),"~blog/default/blog-post-list-prop-default.json",5513],"8ac6191a":[()=>n.e(8465).then(n.t.bind(n,4540,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-online-feature-store-8eb.json",4540],"8dd2df60":[()=>n.e(1537).then(n.t.bind(n,3359,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-inferflow-541.json",3359],"8ea48c46":[()=>n.e(9824).then(n.bind(n,7956)),"@site/docs/numerix/v1.0.0/release-notes.md",7956],"93f344c7":[()=>n.e(4416).then(n.t.bind(n,5232,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-inferflow-dc1.json",5232],"99009a21":[()=>n.e(4064).then(n.t.bind(n,1161,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-tensorrt-llm-ee4.json",1161],"9aed321e":[()=>n.e(2951).then(n.bind(n,9059)),"@site/docs/inferflow/v1.0.0/release-notes.md",9059],"9d13045e":[()=>n.e(8014).then(n.bind(n,7791)),"@site/docs/inferflow/v1.0.0/configuration.md",7791],"9e4087bc":[()=>n.e(2711).then(n.bind(n,9331)),"@theme/BlogArchivePage",9331],a6aa9e1f:[()=>Promise.all([n.e(1869),n.e(6870),n.e(7518),n.e(7643)]).then(n.bind(n,5124)),"@theme/BlogListPage",5124],a7456010:[()=>n.e(1235).then(n.t.bind(n,8552,19)),"@generated/docusaurus-plugin-content-pages/default/__plugin.json",8552],a7bd4aaa:[()=>n.e(7098).then(n.bind(n,1723)),"@theme/DocVersionRoot",1723],a94703ab:[()=>Promise.all([n.e(1869),n.e(9048)]).then(n.bind(n,1377)),"@theme/DocRoot",1377],a97f18d9:[()=>n.e(6724).then(n.bind(n,4215)),"@site/blog/bharatmlstack-history/post-two/index.md?truncated=true",4215],aaabe254:[()=>n.e(770).then(n.t.bind(n,1982,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-bharatmlstack-205.json",1982],aba21aa0:[()=>n.e(5742).then(n.t.bind(n,7093,19)),"@generated/docusaurus-plugin-content-docs/default/__plugin.json",7093],ac51638e:[()=>n.e(9473).then(n.bind(n,6692)),"@site/docs/sdks/python/v1.0.0/spark_feature_push_client.md",6692],acecf23e:[()=>n.e(1903).then(n.t.bind(n,1912,19)),"~blog/default/blogMetadata-default.json",1912],adb039a4:[()=>n.e(7609).then(n.t.bind(n,926,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-llm-025.json",926],be9e6e2d:[()=>n.e(7871).then(n.t.bind(n,3405,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-embedding-search-672.json",3405],c4822c4f:[()=>n.e(1915).then(n.bind(n,3649)),"@site/docs/online-feature-store/v1.0.0/functionalities.md",3649],c4f5d8e4:[()=>Promise.all([n.e(1869),n.e(2634)]).then(n.bind(n,6467)),"@site/src/pages/index.js",6467],c7b64fcc:[()=>n.e(8933).then(n.t.bind(n,9997,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-go-sdk-b5b.json",9997],ccc49370:[()=>Promise.all([n.e(1869),n.e(6870),n.e(7518),n.e(3249)]).then(n.bind(n,3858)),"@theme/BlogPostPage",3858],d152284c:[()=>n.e(1606).then(n.bind(n,5876)),"@site/docs/online-feature-store/v1.0.0/release-notes.md",5876],e66382f6:[()=>n.e(1405).then(n.bind(n,9563)),"@site/docs/online-feature-store/v1.0.0/architecture.md",9563],e8202a51:[()=>n.e(2771).then(n.bind(n,1185)),"@site/docs/numerix/v1.0.0/benchmarks.md",1185],f2c141e4:[()=>n.e(1909).then(n.bind(n,161)),"@site/blog/bharatmlstack-history/post-one/index.md?truncated=true",161],f9755c6e:[()=>n.e(8315).then(n.bind(n,8319)),"@site/blog/bharatmlstack-history/post-five/index.md?truncated=true",8319],f994c8da:[()=>n.e(1999).then(n.t.bind(n,38,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-7a3.json",38],fa31f022:[()=>n.e(6062).then(n.t.bind(n,6096,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-v-100-ae3.json",6096],fccc4c42:[()=>n.e(2117).then(n.bind(n,2561)),"@site/blog/bharatmlstack-history/post-three/index.md?truncated=true",2561],fcf4f6ca:[()=>n.e(7720).then(n.t.bind(n,4041,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-trufflebox-ui-b39.json",4041]};var l=n(4848);function s({error:e,retry:t,pastDelay:n}){return e?(0,l.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,l.jsx)("p",{children:String(e)}),(0,l.jsx)("div",{children:(0,l.jsx)("button",{type:"button",onClick:t,children:"Retry"})})]}):n?(0,l.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,l.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,l.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,l.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,l.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,l.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,l.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,l.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,l.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var c=n(6921),u=n(3102);function d(e,t){if("*"===e)return a()({loading:s,loader:()=>n.e(2237).then(n.bind(n,2237)),modules:["@theme/NotFound"],webpack:()=>[2237],render(e,t){const n=e.default;return(0,l.jsx)(u.W,{value:{plugin:{name:"native",id:"default"}},children:(0,l.jsx)(n,{...t})})}});const r=o[`${e}-${t}`],d={},f=[],p=[],h=(0,c.A)(r);return Object.entries(h).forEach(([e,t])=>{const n=i[t];n&&(d[e]=n[0],f.push(n[1]),p.push(n[2]))}),a().Map({loading:s,loader:d,modules:f,webpack:()=>p,render(t,n){const a=JSON.parse(JSON.stringify(r));Object.entries(t).forEach(([t,n])=>{const r=n.default;if(!r)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof r&&"function"!=typeof r||Object.keys(n).filter(e=>"default"!==e).forEach(e=>{r[e]=n[e]});let o=a;const i=t.split(".");i.slice(0,-1).forEach(e=>{o=o[e]}),o[i[i.length-1]]=r});const o=a.__comp;delete a.__comp;const i=a.__context;delete a.__context;const s=a.__props;return delete a.__props,(0,l.jsx)(u.W,{value:i,children:(0,l.jsx)(o,{...a,...s,...n})})}})}const f=[{path:"/BharatMLStack/blog",component:d("/BharatMLStack/blog","f21"),exact:!0},{path:"/BharatMLStack/blog/archive",component:d("/BharatMLStack/blog/archive","dde"),exact:!0},{path:"/BharatMLStack/blog/authors",component:d("/BharatMLStack/blog/authors","f47"),exact:!0},{path:"/BharatMLStack/blog/post-five",component:d("/BharatMLStack/blog/post-five","0ec"),exact:!0},{path:"/BharatMLStack/blog/post-one",component:d("/BharatMLStack/blog/post-one","e5f"),exact:!0},{path:"/BharatMLStack/blog/post-three",component:d("/BharatMLStack/blog/post-three","be5"),exact:!0},{path:"/BharatMLStack/blog/post-three",component:d("/BharatMLStack/blog/post-three","85f"),exact:!0},{path:"/BharatMLStack/blog/post-two",component:d("/BharatMLStack/blog/post-two","5a0"),exact:!0},{path:"/BharatMLStack/blog/tags",component:d("/BharatMLStack/blog/tags","8af"),exact:!0},{path:"/BharatMLStack/blog/tags/bharatmlstack",component:d("/BharatMLStack/blog/tags/bharatmlstack","0c5"),exact:!0},{path:"/BharatMLStack/blog/tags/embedding-search",component:d("/BharatMLStack/blog/tags/embedding-search","27a"),exact:!0},{path:"/BharatMLStack/blog/tags/inferflow",component:d("/BharatMLStack/blog/tags/inferflow","9d9"),exact:!0},{path:"/BharatMLStack/blog/tags/interaction-store",component:d("/BharatMLStack/blog/tags/interaction-store","c75"),exact:!0},{path:"/BharatMLStack/blog/tags/llm",component:d("/BharatMLStack/blog/tags/llm","fa9"),exact:!0},{path:"/BharatMLStack/blog/tags/meesho",component:d("/BharatMLStack/blog/tags/meesho","e82"),exact:!0},{path:"/BharatMLStack/blog/tags/mlplatform",component:d("/BharatMLStack/blog/tags/mlplatform","856"),exact:!0},{path:"/BharatMLStack/blog/tags/model-inference",component:d("/BharatMLStack/blog/tags/model-inference","efa"),exact:!0},{path:"/BharatMLStack/blog/tags/online-feature-store",component:d("/BharatMLStack/blog/tags/online-feature-store","44b"),exact:!0},{path:"/BharatMLStack/blog/tags/tensorrt-llm",component:d("/BharatMLStack/blog/tags/tensorrt-llm","bec"),exact:!0},{path:"/BharatMLStack/blog/tags/vllm",component:d("/BharatMLStack/blog/tags/vllm","bd3"),exact:!0},{path:"/BharatMLStack/markdown-page",component:d("/BharatMLStack/markdown-page","747"),exact:!0},{path:"/BharatMLStack/",component:d("/BharatMLStack/","e34"),exact:!0},{path:"/BharatMLStack/",component:d("/BharatMLStack/","c10"),routes:[{path:"/BharatMLStack/",component:d("/BharatMLStack/","11b"),routes:[{path:"/BharatMLStack/",component:d("/BharatMLStack/","4d0"),routes:[{path:"/BharatMLStack/category/go-sdk",component:d("/BharatMLStack/category/go-sdk","6b0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/category/inferflow",component:d("/BharatMLStack/category/inferflow","e9f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/category/numerix",component:d("/BharatMLStack/category/numerix","703"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/category/online-feature-store",component:d("/BharatMLStack/category/online-feature-store","7ee"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/category/python-sdk",component:d("/BharatMLStack/category/python-sdk","1fd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/category/quick-start",component:d("/BharatMLStack/category/quick-start","dff"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/category/sdks",component:d("/BharatMLStack/category/sdks","532"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/category/trufflebox-ui",component:d("/BharatMLStack/category/trufflebox-ui","5f5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/category/v100",component:d("/BharatMLStack/category/v100","ddd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/inferflow/v1.0.0",component:d("/BharatMLStack/inferflow/v1.0.0","018"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/inferflow/v1.0.0/architecture",component:d("/BharatMLStack/inferflow/v1.0.0/architecture","46b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/inferflow/v1.0.0/configuration",component:d("/BharatMLStack/inferflow/v1.0.0/configuration","4ef"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/inferflow/v1.0.0/functionalities",component:d("/BharatMLStack/inferflow/v1.0.0/functionalities","65a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/inferflow/v1.0.0/release-notes",component:d("/BharatMLStack/inferflow/v1.0.0/release-notes","cce"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/numerix/v1.0.0",component:d("/BharatMLStack/numerix/v1.0.0","441"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/numerix/v1.0.0/architecture",component:d("/BharatMLStack/numerix/v1.0.0/architecture","4d9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/numerix/v1.0.0/benchmarks",component:d("/BharatMLStack/numerix/v1.0.0/benchmarks","eae"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/numerix/v1.0.0/functionalities",component:d("/BharatMLStack/numerix/v1.0.0/functionalities","f7b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/numerix/v1.0.0/release-notes",component:d("/BharatMLStack/numerix/v1.0.0/release-notes","77b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/online-feature-store/v1.0.0",component:d("/BharatMLStack/online-feature-store/v1.0.0","218"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/online-feature-store/v1.0.0/architecture",component:d("/BharatMLStack/online-feature-store/v1.0.0/architecture","0af"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/online-feature-store/v1.0.0/benchmarks",component:d("/BharatMLStack/online-feature-store/v1.0.0/benchmarks","889"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/online-feature-store/v1.0.0/data-formats",component:d("/BharatMLStack/online-feature-store/v1.0.0/data-formats","46e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/online-feature-store/v1.0.0/functionalities",component:d("/BharatMLStack/online-feature-store/v1.0.0/functionalities","415"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/online-feature-store/v1.0.0/release-notes",component:d("/BharatMLStack/online-feature-store/v1.0.0/release-notes","36c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/quick-start/v1.0.0/quick-start",component:d("/BharatMLStack/quick-start/v1.0.0/quick-start","b19"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/sdks/go/v1.0.0/feature_client",component:d("/BharatMLStack/sdks/go/v1.0.0/feature_client","1df"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client",component:d("/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client","9dc"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client",component:d("/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client","1bc"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/trufflebox-ui/v1.0.0/userguide",component:d("/BharatMLStack/trufflebox-ui/v1.0.0/userguide","65e"),exact:!0,sidebar:"tutorialSidebar"}]}]}]},{path:"*",component:d("*")}]},8380:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n<r;n++)t[e[n]]=!0;return t}function r(e){var n={},r=[];function a(r,o){if(!(r in n)){o.push(r);var i=o.indexOf(r);if(i<o.length-1)throw new Error("Circular dependency: "+o.slice(i).join(" -> "));var l={},s=e[r];if(s){function c(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in a(t,o),l[t]=!0,n[t])l[i]=!0}t(s.require,c),t(s.optional,c),t(s.modify,c)}n[r]=l,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),c=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a})}return n[r]||r}}(s);i=i.map(c),l=(l||[]).map(c);var u=n(i),d=n(l);i.forEach(function e(n){var r=s[n];t(r&&r.require,function(t){t in d||(u[t]=!0,e(t))})});for(var f,p=r(s),h=u;a(h);){for(var m in f={},h){var g=s[m];t(g&&g.modify,function(e){e in d&&(f[e]=!0)})}for(var b in d)if(!(b in u))for(var y in p(b))if(y in u){f[b]=!0;break}for(var v in h=f)u[v]=!0}var w={getIds:function(){var e=[];return w.load(function(t){e.push(t)}),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,l={},s={};function c(e){if(e in l)return l[e];s[e]=!0;var a,u=[];for(var d in t(e))d in n&&u.push(d);if(0===u.length)a=r(e);else{var f=i(u.map(function(e){var t=c(e);return delete s[e],t}));o?a=o(f,function(){return r(e)}):r(e)}return l[e]=a}for(var u in n)c(u);var d=[];for(var f in s)d.push(l[f]);return i(d)}(p,u,t,n)}};return w}}();e.exports=t},8505:(e,t,n)=>{var r=n(4634);e.exports=m,e.exports.parse=o,e.exports.compile=function(e,t){return c(o(e,t),t)},e.exports.tokensToFunction=c,e.exports.tokensToRegExp=h;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,l=0,s="",c=t&&t.delimiter||"/";null!=(n=a.exec(e));){var u=n[0],f=n[1],p=n.index;if(s+=e.slice(l,p),l=p+u.length,f)s+=f[1];else{var h=e[l],m=n[2],g=n[3],b=n[4],y=n[5],v=n[6],w=n[7];s&&(r.push(s),s="");var k=null!=m&&null!=h&&h!==m,S="+"===v||"*"===v,x="?"===v||"*"===v,_=m||c,E=b||y,C=m||("string"==typeof r[r.length-1]?r[r.length-1]:"");r.push({name:g||o++,prefix:m||"",delimiter:_,optional:x,repeat:S,partial:k,asterisk:!!w,pattern:E?d(E):w?".*":i(_,C)})}}return l<e.length&&(s+=e.substr(l)),s&&r.push(s),r}function i(e,t){return!t||t.indexOf(e)>-1?"[^"+u(e)+"]+?":u(t)+"|(?:(?!"+u(t)+")[^"+u(e)+"])+?"}function l(e){return encodeURI(e).replace(/[\/?#]/g,function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})}function s(e){return encodeURI(e).replace(/[?#]/g,function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})}function c(e,t){for(var n=new Array(e.length),a=0;a<e.length;a++)"object"==typeof e[a]&&(n[a]=new RegExp("^(?:"+e[a].pattern+")$",p(t)));return function(t,a){for(var o="",i=t||{},c=(a||{}).pretty?l:encodeURIComponent,u=0;u<e.length;u++){var d=e[u];if("string"!=typeof d){var f,p=i[d.name];if(null==p){if(d.optional){d.partial&&(o+=d.prefix);continue}throw new TypeError('Expected "'+d.name+'" to be defined')}if(r(p)){if(!d.repeat)throw new TypeError('Expected "'+d.name+'" to not repeat, but received `'+JSON.stringify(p)+"`");if(0===p.length){if(d.optional)continue;throw new TypeError('Expected "'+d.name+'" to not be empty')}for(var h=0;h<p.length;h++){if(f=c(p[h]),!n[u].test(f))throw new TypeError('Expected all "'+d.name+'" to match "'+d.pattern+'", but received `'+JSON.stringify(f)+"`");o+=(0===h?d.prefix:d.delimiter)+f}}else{if(f=d.asterisk?s(p):c(p),!n[u].test(f))throw new TypeError('Expected "'+d.name+'" to match "'+d.pattern+'", but received "'+f+'"');o+=d.prefix+f}}else o+=d}return o}}function u(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function d(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function f(e,t){return e.keys=t,e}function p(e){return e&&e.sensitive?"":"i"}function h(e,t,n){r(t)||(n=t||n,t=[]);for(var a=(n=n||{}).strict,o=!1!==n.end,i="",l=0;l<e.length;l++){var s=e[l];if("string"==typeof s)i+=u(s);else{var c=u(s.prefix),d="(?:"+s.pattern+")";t.push(s),s.repeat&&(d+="(?:"+c+d+")*"),i+=d=s.optional?s.partial?c+"("+d+")?":"(?:"+c+"("+d+"))?":c+"("+d+")"}}var h=u(n.delimiter||"/"),m=i.slice(-h.length)===h;return a||(i=(m?i.slice(0,-h.length):i)+"(?:"+h+"(?=$))?"),i+=o?"$":a&&m?"":"(?="+h+"|$)",f(new RegExp("^"+i,p(n)),t)}function m(e,t,n){return r(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r<n.length;r++)t.push({name:r,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return f(e,t)}(e,t):r(e)?function(e,t,n){for(var r=[],a=0;a<e.length;a++)r.push(m(e[a],t,n).source);return f(new RegExp("(?:"+r.join("|")+")",p(n)),t)}(e,t,n):function(e,t,n){return h(o(e,n),t,n)}(e,t,n)}},8587:(e,t,n)=>{"use strict";function r(e,t){if(null==e)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==t.indexOf(r))continue;n[r]=e[r]}return n}n.d(t,{A:()=>r})},8600:(e,t,n)=>{"use strict";var r=n(6540),a=n(5338),o=n(545),i=n(4625),l=n(4784),s=n(8193);const c=[n(3001),n(119),n(6134),n(6294),n(1043)];var u=n(8328),d=n(6347),f=n(2831),p=n(4848);function h({children:e}){return(0,p.jsx)(p.Fragment,{children:e})}var m=n(4563);const g=e=>e.defaultFormatter(e);function b({children:e}){return(0,p.jsx)(m.AL,{formatter:g,children:e})}function y({children:e}){return(0,p.jsx)(b,{children:e})}var v=n(5260),w=n(4586),k=n(6025),S=n(6342),x=n(5500),_=n(2131),E=n(4090);var C=n(440),A=n(1463);function L(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,w.A)(),r=(0,_.o)(),a=n[e].htmlLang,o=e=>e.replace("-","_");return(0,p.jsxs)(v.A,{children:[Object.entries(n).map(([e,{htmlLang:t}])=>(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:e,fullyQualified:!0}),hrefLang:t},e)),(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,p.jsx)("meta",{property:"og:locale",content:o(a)}),Object.values(n).filter(e=>a!==e.htmlLang).map(e=>(0,p.jsx)("meta",{property:"og:locale:alternate",content:o(e.htmlLang)},`meta-og-${e.htmlLang}`))]})}function T({permalink:e}){const{siteConfig:{url:t}}=(0,w.A)(),n=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,w.A)(),{pathname:r}=(0,d.zy)();return e+(0,C.Ks)((0,k.Ay)(r),{trailingSlash:n,baseUrl:t})}(),r=e?`${t}${e}`:n;return(0,p.jsxs)(v.A,{children:[(0,p.jsx)("meta",{property:"og:url",content:r}),(0,p.jsx)("link",{rel:"canonical",href:r})]})}function j(){const{i18n:{currentLocale:e}}=(0,w.A)(),{metadata:t,image:n}=(0,S.p)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(v.A,{children:[(0,p.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,p.jsx)("body",{className:E.w})]}),n&&(0,p.jsx)(x.be,{image:n}),(0,p.jsx)(T,{}),(0,p.jsx)(L,{}),(0,p.jsx)(A.A,{tag:"default",locale:e}),(0,p.jsx)(v.A,{children:t.map((e,t)=>(0,p.jsx)("meta",{...e},t))})]})}const P=new Map;var M=n(6125),N=n(6988),O=n(205);function R(e,...t){const n=c.map(n=>{const r=n.default?.[e]??n[e];return r?.(...t)});return()=>n.forEach(e=>e?.())}const D=function({children:e,location:t,previousLocation:n}){return(0,O.A)(()=>{n!==t&&(!function({location:e,previousLocation:t}){if(!t)return;const n=e.pathname===t.pathname,r=e.hash===t.hash,a=e.search===t.search;if(n&&r&&!a)return;const{hash:o}=e;if(o){const e=decodeURIComponent(o.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:t,previousLocation:n}),R("onRouteDidUpdate",{previousLocation:n,location:t}))},[n,t]),e};function B(e){const t=Array.from(new Set([e,decodeURI(e)])).map(e=>(0,f.u)(u.A,e)).flat();return Promise.all(t.map(e=>e.route.component.preload?.()))}class F extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.A.canUseDOM?R("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=R("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),B(n.pathname).then(()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})}).catch(e=>{console.warn(e),window.location.reload()}),!1}render(){const{children:e,location:t}=this.props;return(0,p.jsx)(D,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(d.qh,{location:t,render:()=>e})})}}const I=F,z="__docusaurus-base-url-issue-banner-suggestion-container";function $(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '__docusaurus-base-url-issue-banner-container';\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="__docusaurus-base-url-issue-banner" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${z}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n document.body.prepend(bannerContainer);\n var suggestionContainer = document.getElementById('${z}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function U(){const{siteConfig:{baseUrl:e}}=(0,w.A)();return(0,p.jsx)(p.Fragment,{children:!s.A.canUseDOM&&(0,p.jsx)(v.A,{children:(0,p.jsx)("script",{children:$(e)})})})}function q(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,w.A)(),{pathname:n}=(0,d.zy)();return t&&n===e?(0,p.jsx)(U,{}):null}function H(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:r,localeConfigs:a}}=(0,w.A)(),o=(0,k.Ay)(e),{htmlLang:i,direction:l}=a[r];return(0,p.jsxs)(v.A,{children:[(0,p.jsx)("html",{lang:i,dir:l}),(0,p.jsx)("title",{children:t}),(0,p.jsx)("meta",{property:"og:title",content:t}),(0,p.jsx)("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&(0,p.jsx)("meta",{name:"robots",content:"noindex, nofollow"}),e&&(0,p.jsx)("link",{rel:"icon",href:o})]})}var G=n(7489),V=n(2303);function W(){const e=(0,V.A)();return(0,p.jsx)(v.A,{children:(0,p.jsx)("html",{"data-has-hydrated":e})})}const Q=(0,f.v)(u.A);function K(){const e=function(e){if(P.has(e.pathname))return{...e,pathname:P.get(e.pathname)};if((0,f.u)(u.A,e.pathname).some(({route:e})=>!0===e.exact))return P.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return P.set(e.pathname,t),{...e,pathname:t}}((0,d.zy)());return(0,p.jsx)(I,{location:e,children:Q})}function Y(){return(0,p.jsx)(G.A,{children:(0,p.jsx)(N.l,{children:(0,p.jsxs)(M.x,{children:[(0,p.jsx)(h,{children:(0,p.jsxs)(y,{children:[(0,p.jsx)(H,{}),(0,p.jsx)(j,{}),(0,p.jsx)(q,{}),(0,p.jsx)(K,{})]})}),(0,p.jsx)(W,{})]})})})}var X=n(4054);const Z=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)})}:function(e){return new Promise((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)})};var J=n(6921);const ee=new Set,te=new Set,ne=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,re={prefetch:e=>{if(!(e=>!ne()&&!te.has(e)&&!ee.has(e))(e))return!1;ee.add(e);const t=(0,f.u)(u.A,e).flatMap(e=>{return t=e.route.path,Object.entries(X).filter(([e])=>e.replace(/-[^-]+$/,"")===t).flatMap(([,e])=>Object.values((0,J.A)(e)));var t});return Promise.all(t.map(e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Z(t).catch(()=>{}):Promise.resolve()}))},preload:e=>!!(e=>!ne()&&!te.has(e))(e)&&(te.add(e),B(e))},ae=Object.freeze(re);function oe({children:e}){return"hash"===l.default.future.experimental_router?(0,p.jsx)(i.I9,{children:e}):(0,p.jsx)(i.Kd,{children:e})}const ie=Boolean(!0);if(s.A.canUseDOM){window.docusaurus=ae;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(o.vd,{children:(0,p.jsx)(oe,{children:(0,p.jsx)(Y,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},i=()=>{if(window.docusaurusRoot)window.docusaurusRoot.render(t);else if(ie)window.docusaurusRoot=a.hydrateRoot(e,t,{onRecoverableError:n});else{const r=a.createRoot(e,{onRecoverableError:n});r.render(t),window.docusaurusRoot=r}};B(window.location.pathname).then(()=>{(0,r.startTransition)(i)})}},8692:(e,t,n)=>{var r={"./":8722};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=8692},8722:(e,t,n)=>{const r=n(6969),a=n(8380),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter(e=>"meta"!=e):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load(e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(3157).resolve(t)],delete Prism.languages[e],n(3157)(t),o.add(e)})}i.silent=!1,e.exports=i},8774:(e,t,n)=>{"use strict";n.d(t,{A:()=>p});var r=n(6540),a=n(4625),o=n(440),i=n(4586),l=n(6654),s=n(8193),c=n(3427),u=n(6025),d=n(4848);function f({isNavLink:e,to:t,href:n,activeClassName:f,isActive:p,"data-noBrokenLinkCheck":h,autoAddBaseUrl:m=!0,...g},b){const{siteConfig:y}=(0,i.A)(),{trailingSlash:v,baseUrl:w}=y,k=y.future.experimental_router,{withBaseUrl:S}=(0,u.hH)(),x=(0,c.A)(),_=(0,r.useRef)(null);(0,r.useImperativeHandle)(b,()=>_.current);const E=t||n;const C=(0,l.A)(E),A=E?.replace("pathname://","");let L=void 0!==A?(T=A,m&&(e=>e.startsWith("/"))(T)?S(T):T):void 0;var T;"hash"===k&&L?.startsWith("./")&&(L=L?.slice(1)),L&&C&&(L=(0,o.Ks)(L,{trailingSlash:v,baseUrl:w}));const j=(0,r.useRef)(!1),P=e?a.k2:a.N_,M=s.A.canUseIntersectionObserver,N=(0,r.useRef)(),O=()=>{j.current||null==L||(window.docusaurus.preload(L),j.current=!0)};(0,r.useEffect)(()=>(!M&&C&&s.A.canUseDOM&&null!=L&&window.docusaurus.prefetch(L),()=>{M&&N.current&&N.current.disconnect()}),[N,L,M,C]);const R=L?.startsWith("#")??!1,D=!g.target||"_self"===g.target,B=!L||!C||!D||R&&"hash"!==k;h||!R&&B||x.collectLink(L),g.id&&x.collectAnchor(g.id);const F={};return B?(0,d.jsx)("a",{ref:_,href:L,...E&&!C&&{target:"_blank",rel:"noopener noreferrer"},...g,...F}):(0,d.jsx)(P,{...g,onMouseEnter:O,onTouchStart:O,innerRef:e=>{_.current=e,M&&e&&C&&(N.current=new window.IntersectionObserver(t=>{t.forEach(t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(N.current.unobserve(e),N.current.disconnect(),null!=L&&window.docusaurus.prefetch(L))})}),N.current.observe(e))},to:L,...e&&{isActive:p,activeClassName:f},...F})}const p=r.forwardRef(f)},9169:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>l,ys:()=>i});var r=n(6540),a=n(8328),o=n(4586);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function l(){const{baseUrl:e}=(0,o.A)().siteConfig;return(0,r.useMemo)(()=>function({baseUrl:e,routes:t}){function n(t){return t.path===e&&!0===t.exact}function r(t){return t.path===e&&!t.exact}return function e(t){if(0===t.length)return;return t.find(n)||e(t.filter(r).flatMap(e=>e.routes??[]))}(t)}({routes:a.A,baseUrl:e}),[e])}},9532:(e,t,n)=>{"use strict";n.d(t,{Be:()=>c,ZC:()=>l,_q:()=>i,dV:()=>s,fM:()=>u});var r=n(6540),a=n(205),o=n(4848);function i(e){const t=(0,r.useRef)(e);return(0,a.A)(()=>{t.current=e},[e]),(0,r.useCallback)((...e)=>t.current(...e),[])}function l(e){const t=(0,r.useRef)();return(0,a.A)(()=>{t.current=e}),t.current}class s extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function c(e){const t=Object.entries(e);return t.sort((e,t)=>e[0].localeCompare(t[0])),(0,r.useMemo)(()=>e,t.flat())}function u(e){return({children:t})=>(0,o.jsx)(o.Fragment,{children:e.reduceRight((e,t)=>(0,o.jsx)(t,{children:e}),t)})}},9698:(e,t)=>{"use strict";var n=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function a(e,t,r){var a=null;if(void 0!==r&&(a=""+r),void 0!==t.key&&(a=""+t.key),"key"in t)for(var o in r={},t)"key"!==o&&(r[o]=t[o]);else r=t;return t=r.ref,{$$typeof:n,type:e,key:a,ref:void 0!==t?t:null,props:r}}t.Fragment=r,t.jsx=a,t.jsxs=a},9700:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,function(e){if("function"==typeof o&&!o(e))return e;for(var a,l=i.length;-1!==n.code.indexOf(a=t(r,l));)++l;return i[l]=e,a}),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(l){for(var s=0;s<l.length&&!(a>=o.length);s++){var c=l[s];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[a],d=n.tokenStack[u],f="string"==typeof c?c:c.content,p=t(r,u),h=f.indexOf(p);if(h>-1){++a;var m=f.substring(0,h),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=f.substring(h+p.length),y=[];m&&y.push.apply(y,i([m])),y.push(g),b&&y.push.apply(y,i([b])),"string"==typeof c?l.splice.apply(l,[s,1].concat(y)):c.content=y}}else c.content&&i(c.content)}return l}(n.tokens)}}}})}(Prism)},9869:(e,t)=>{"use strict";var n=Symbol.for("react.transitional.element"),r=Symbol.for("react.portal"),a=Symbol.for("react.fragment"),o=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),l=Symbol.for("react.consumer"),s=Symbol.for("react.context"),c=Symbol.for("react.forward_ref"),u=Symbol.for("react.suspense"),d=Symbol.for("react.memo"),f=Symbol.for("react.lazy"),p=Symbol.iterator;var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},m=Object.assign,g={};function b(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||h}function y(){}function v(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||h}b.prototype.isReactComponent={},b.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},b.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},y.prototype=b.prototype;var w=v.prototype=new y;w.constructor=v,m(w,b.prototype),w.isPureReactComponent=!0;var k=Array.isArray,S={H:null,A:null,T:null,S:null,V:null},x=Object.prototype.hasOwnProperty;function _(e,t,r,a,o,i){return r=i.ref,{$$typeof:n,type:e,key:t,ref:void 0!==r?r:null,props:i}}function E(e){return"object"==typeof e&&null!==e&&e.$$typeof===n}var C=/\/+/g;function A(e,t){return"object"==typeof e&&null!==e&&null!=e.key?(n=""+e.key,r={"=":"=0",":":"=2"},"$"+n.replace(/[=:]/g,function(e){return r[e]})):t.toString(36);var n,r}function L(){}function T(e,t,a,o,i){var l=typeof e;"undefined"!==l&&"boolean"!==l||(e=null);var s,c,u=!1;if(null===e)u=!0;else switch(l){case"bigint":case"string":case"number":u=!0;break;case"object":switch(e.$$typeof){case n:case r:u=!0;break;case f:return T((u=e._init)(e._payload),t,a,o,i)}}if(u)return i=i(e),u=""===o?"."+A(e,0):o,k(i)?(a="",null!=u&&(a=u.replace(C,"$&/")+"/"),T(i,t,a,"",function(e){return e})):null!=i&&(E(i)&&(s=i,c=a+(null==i.key||e&&e.key===i.key?"":(""+i.key).replace(C,"$&/")+"/")+u,i=_(s.type,c,void 0,0,0,s.props)),t.push(i)),1;u=0;var d,h=""===o?".":o+":";if(k(e))for(var m=0;m<e.length;m++)u+=T(o=e[m],t,a,l=h+A(o,m),i);else if("function"==typeof(m=null===(d=e)||"object"!=typeof d?null:"function"==typeof(d=p&&d[p]||d["@@iterator"])?d:null))for(e=m.call(e),m=0;!(o=e.next()).done;)u+=T(o=o.value,t,a,l=h+A(o,m++),i);else if("object"===l){if("function"==typeof e.then)return T(function(e){switch(e.status){case"fulfilled":return e.value;case"rejected":throw e.reason;default:switch("string"==typeof e.status?e.then(L,L):(e.status="pending",e.then(function(t){"pending"===e.status&&(e.status="fulfilled",e.value=t)},function(t){"pending"===e.status&&(e.status="rejected",e.reason=t)})),e.status){case"fulfilled":return e.value;case"rejected":throw e.reason}}throw e}(e),t,a,o,i);throw t=String(e),Error("Objects are not valid as a React child (found: "+("[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.")}return u}function j(e,t,n){if(null==e)return e;var r=[],a=0;return T(e,r,"","",function(e){return t.call(n,e,a++)}),r}function P(e){if(-1===e._status){var t=e._result;(t=t()).then(function(t){0!==e._status&&-1!==e._status||(e._status=1,e._result=t)},function(t){0!==e._status&&-1!==e._status||(e._status=2,e._result=t)}),-1===e._status&&(e._status=0,e._result=t)}if(1===e._status)return e._result.default;throw e._result}var M="function"==typeof reportError?reportError:function(e){if("object"==typeof window&&"function"==typeof window.ErrorEvent){var t=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:"object"==typeof e&&null!==e&&"string"==typeof e.message?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if("object"==typeof process&&"function"==typeof process.emit)return void process.emit("uncaughtException",e);console.error(e)};function N(){}t.Children={map:j,forEach:function(e,t,n){j(e,function(){t.apply(this,arguments)},n)},count:function(e){var t=0;return j(e,function(){t++}),t},toArray:function(e){return j(e,function(e){return e})||[]},only:function(e){if(!E(e))throw Error("React.Children.only expected to receive a single React element child.");return e}},t.Component=b,t.Fragment=a,t.Profiler=i,t.PureComponent=v,t.StrictMode=o,t.Suspense=u,t.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=S,t.__COMPILER_RUNTIME={__proto__:null,c:function(e){return S.H.useMemoCache(e)}},t.cache=function(e){return function(){return e.apply(null,arguments)}},t.cloneElement=function(e,t,n){if(null==e)throw Error("The argument must be a React element, but you passed "+e+".");var r=m({},e.props),a=e.key;if(null!=t)for(o in void 0!==t.ref&&void 0,void 0!==t.key&&(a=""+t.key),t)!x.call(t,o)||"key"===o||"__self"===o||"__source"===o||"ref"===o&&void 0===t.ref||(r[o]=t[o]);var o=arguments.length-2;if(1===o)r.children=n;else if(1<o){for(var i=Array(o),l=0;l<o;l++)i[l]=arguments[l+2];r.children=i}return _(e.type,a,void 0,0,0,r)},t.createContext=function(e){return(e={$$typeof:s,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider=e,e.Consumer={$$typeof:l,_context:e},e},t.createElement=function(e,t,n){var r,a={},o=null;if(null!=t)for(r in void 0!==t.key&&(o=""+t.key),t)x.call(t,r)&&"key"!==r&&"__self"!==r&&"__source"!==r&&(a[r]=t[r]);var i=arguments.length-2;if(1===i)a.children=n;else if(1<i){for(var l=Array(i),s=0;s<i;s++)l[s]=arguments[s+2];a.children=l}if(e&&e.defaultProps)for(r in i=e.defaultProps)void 0===a[r]&&(a[r]=i[r]);return _(e,o,void 0,0,0,a)},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:c,render:e}},t.isValidElement=E,t.lazy=function(e){return{$$typeof:f,_payload:{_status:-1,_result:e},_init:P}},t.memo=function(e,t){return{$$typeof:d,type:e,compare:void 0===t?null:t}},t.startTransition=function(e){var t=S.T,n={};S.T=n;try{var r=e(),a=S.S;null!==a&&a(n,r),"object"==typeof r&&null!==r&&"function"==typeof r.then&&r.then(N,M)}catch(o){M(o)}finally{S.T=t}},t.unstable_useCacheRefresh=function(){return S.H.useCacheRefresh()},t.use=function(e){return S.H.use(e)},t.useActionState=function(e,t,n){return S.H.useActionState(e,t,n)},t.useCallback=function(e,t){return S.H.useCallback(e,t)},t.useContext=function(e){return S.H.useContext(e)},t.useDebugValue=function(){},t.useDeferredValue=function(e,t){return S.H.useDeferredValue(e,t)},t.useEffect=function(e,t,n){var r=S.H;if("function"==typeof n)throw Error("useEffect CRUD overload is not enabled in this build of React.");return r.useEffect(e,t)},t.useId=function(){return S.H.useId()},t.useImperativeHandle=function(e,t,n){return S.H.useImperativeHandle(e,t,n)},t.useInsertionEffect=function(e,t){return S.H.useInsertionEffect(e,t)},t.useLayoutEffect=function(e,t){return S.H.useLayoutEffect(e,t)},t.useMemo=function(e,t){return S.H.useMemo(e,t)},t.useOptimistic=function(e,t){return S.H.useOptimistic(e,t)},t.useReducer=function(e,t,n){return S.H.useReducer(e,t,n)},t.useRef=function(e){return S.H.useRef(e)},t.useState=function(e){return S.H.useState(e)},t.useSyncExternalStore=function(e,t,n){return S.H.useSyncExternalStore(e,t,n)},t.useTransition=function(){return S.H.useTransition()},t.version="19.1.1"},9876:(e,t,n)=>{"use strict";n.d(t,{e:()=>h,M:()=>m});var r=n(6540),a=n(5600),o=n(4581),i=n(6347),l=n(9532);function s(e){!function(e){const t=(0,i.W6)(),n=(0,l._q)(e);(0,r.useEffect)(()=>t.block((e,t)=>n(e,t)),[t,n])}((t,n)=>{if("POP"===n)return e(t,n)})}var c=n(6342),u=n(4848);const d=r.createContext(void 0);function f(){const e=function(){const e=(0,a.YL)(),{items:t}=(0,c.p)().navbar;return 0===t.length&&!e.component}(),t=(0,o.l)(),n=!e&&"mobile"===t,[i,l]=(0,r.useState)(!1),s=(0,r.useCallback)(()=>{l(e=>!e)},[]);return(0,r.useEffect)(()=>{"desktop"===t&&l(!1)},[t]),(0,r.useMemo)(()=>({disabled:e,shouldRender:n,toggle:s,shown:i}),[e,n,s,i])}function p({handler:e}){return s(e),null}function h({children:e}){const t=f();return(0,u.jsxs)(u.Fragment,{children:[t.shown&&(0,u.jsx)(p,{handler:()=>(t.toggle(),!1)}),(0,u.jsx)(d.Provider,{value:t,children:e})]})}function m(){const e=r.useContext(d);if(void 0===e)throw new l.dV("NavbarMobileSidebarProvider");return e}},9982:(e,t,n)=>{"use strict";e.exports=n(4477)}},e=>{e.O(0,[1869],()=>{return t=8600,e(e.s=t);var t});e.O()}]); \ No newline at end of file diff --git a/docs/assets/js/main.7cb3cce5.js.LICENSE.txt b/docs/assets/js/main.3e15e71d.js.LICENSE.txt similarity index 100% rename from docs/assets/js/main.7cb3cce5.js.LICENSE.txt rename to docs/assets/js/main.3e15e71d.js.LICENSE.txt diff --git a/docs/assets/js/main.7cb3cce5.js b/docs/assets/js/main.7cb3cce5.js deleted file mode 100644 index a17aa70d..00000000 --- a/docs/assets/js/main.7cb3cce5.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.7cb3cce5.js.LICENSE.txt */ -(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8792],{115:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,a="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function o(e,i){if(e===i)return!0;if(e&&i&&"object"==typeof e&&"object"==typeof i){if(e.constructor!==i.constructor)return!1;var l,s,u,c;if(Array.isArray(e)){if((l=e.length)!=i.length)return!1;for(s=l;0!==s--;)if(!o(e[s],i[s]))return!1;return!0}if(n&&e instanceof Map&&i instanceof Map){if(e.size!==i.size)return!1;for(c=e.entries();!(s=c.next()).done;)if(!i.has(s.value[0]))return!1;for(c=e.entries();!(s=c.next()).done;)if(!o(s.value[1],i.get(s.value[0])))return!1;return!0}if(r&&e instanceof Set&&i instanceof Set){if(e.size!==i.size)return!1;for(c=e.entries();!(s=c.next()).done;)if(!i.has(s.value[0]))return!1;return!0}if(a&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(i)){if((l=e.length)!=i.length)return!1;for(s=l;0!==s--;)if(e[s]!==i[s])return!1;return!0}if(e.constructor===RegExp)return e.source===i.source&&e.flags===i.flags;if(e.valueOf!==Object.prototype.valueOf&&"function"==typeof e.valueOf&&"function"==typeof i.valueOf)return e.valueOf()===i.valueOf();if(e.toString!==Object.prototype.toString&&"function"==typeof e.toString&&"function"==typeof i.toString)return e.toString()===i.toString();if((l=(u=Object.keys(e)).length)!==Object.keys(i).length)return!1;for(s=l;0!==s--;)if(!Object.prototype.hasOwnProperty.call(i,u[s]))return!1;if(t&&e instanceof Element)return!1;for(s=l;0!==s--;)if(("_owner"!==u[s]&&"__v"!==u[s]&&"__o"!==u[s]||!e.$$typeof)&&!o(e[u[s]],i[u[s]]))return!1;return!0}return e!=e&&i!=i}e.exports=function(e,t){try{return o(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},119:(e,t,n)=>{"use strict";n.r(t)},205:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(6540);const a=n(8193).A.canUseDOM?r.useLayoutEffect:r.useEffect},253:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=function e(t){if(t.cause)return[t,...e(t.cause)];return[t]}},311:e=>{"use strict";e.exports=function(e,t,n,r,a,o,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,r,a,o,i,l],c=0;(s=new Error(t.replace(/%s/g,(function(){return u[c++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},418:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});const r=()=>null},440:(e,t,n)=>{"use strict";t.rA=t.Ks=t.LU=void 0;const r=n(1635);t.LU="__blog-post-container";var a=n(2983);Object.defineProperty(t,"Ks",{enumerable:!0,get:function(){return r.__importDefault(a).default}});var o=n(2566);var i=n(253);Object.defineProperty(t,"rA",{enumerable:!0,get:function(){return i.getErrorCausalChain}})},545:(e,t,n)=>{"use strict";n.d(t,{mg:()=>J,vd:()=>G});var r=n(6540),a=n(5556),o=n.n(a),i=n(115),l=n.n(i),s=n(311),u=n.n(s),c=n(2833),d=n.n(c);function f(){return f=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},f.apply(this,arguments)}function p(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,m(e,t)}function m(e,t){return m=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},m(e,t)}function h(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)t.indexOf(n=o[r])>=0||(a[n]=e[n]);return a}var g={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},y={rel:["amphtml","canonical","alternate"]},b={type:["application/ld+json"]},v={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},w=Object.keys(g).map((function(e){return g[e]})),k={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},S=Object.keys(k).reduce((function(e,t){return e[k[t]]=t,e}),{}),x=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},_=function(e){var t=x(e,g.TITLE),n=x(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var r=x(e,"defaultTitle");return t||r||void 0},E=function(e){return x(e,"onChangeClientState")||function(){}},C=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return f({},e,t)}),{})},A=function(e,t){return t.filter((function(e){return void 0!==e[g.BASE]})).map((function(e){return e[g.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),a=0;a<r.length;a+=1){var o=r[a].toLowerCase();if(-1!==e.indexOf(o)&&n[o])return t.concat(n)}return t}),[])},T=function(e,t,n){var r={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var a={};n.filter((function(e){for(var n,o=Object.keys(e),i=0;i<o.length;i+=1){var l=o[i],s=l.toLowerCase();-1===t.indexOf(s)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===s&&"stylesheet"===e[s].toLowerCase()||(n=s),-1===t.indexOf(l)||"innerHTML"!==l&&"cssText"!==l&&"itemprop"!==l||(n=l)}if(!n||!e[n])return!1;var u=e[n].toLowerCase();return r[n]||(r[n]={}),a[n]||(a[n]={}),!r[n][u]&&(a[n][u]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var o=Object.keys(a),i=0;i<o.length;i+=1){var l=o[i],s=f({},r[l],a[l]);r[l]=s}return e}),[]).reverse()},L=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},j=function(e){return Array.isArray(e)?e.join(""):e},P=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),r=0;r<n.length;r+=1)if(t[n[r]]&&t[n[r]].includes(e[n[r]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},N=function(e,t){var n;return f({},e,((n={})[t]=void 0,n))},O=[g.NOSCRIPT,g.SCRIPT,g.STYLE],R=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},M=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},D=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[k[n]||n]=e[n],t}),t)},F=function(e,t){return t.map((function(t,n){var a,o=((a={key:n})["data-rh"]=!0,a);return Object.keys(t).forEach((function(e){var n=k[e]||e;"innerHTML"===n||"cssText"===n?o.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:o[n]=t[e]})),r.createElement(e,o)}))},I=function(e,t,n){switch(e){case g.TITLE:return{toComponent:function(){return n=t.titleAttributes,(a={key:e=t.title})["data-rh"]=!0,o=D(n,a),[r.createElement(g.TITLE,o,e)];var e,n,a,o},toString:function(){return function(e,t,n,r){var a=M(n),o=j(t);return a?"<"+e+' data-rh="true" '+a+">"+R(o,r)+"</"+e+">":"<"+e+' data-rh="true">'+R(o,r)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return D(t)},toString:function(){return M(t)}};default:return{toComponent:function(){return F(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var a=Object.keys(r).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var a=void 0===r[t]?t:t+'="'+R(r[t],n)+'"';return e?e+" "+a:a}),""),o=r.innerHTML||r.cssText||"",i=-1===O.indexOf(e);return t+"<"+e+' data-rh="true" '+a+(i?"/>":">"+o+"</"+e+">")}),"")}(e,t,n)}}}},B=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,a=e.htmlAttributes,o=e.noscriptTags,i=e.styleTags,l=e.title,s=void 0===l?"":l,u=e.titleAttributes,c=e.linkTags,d=e.metaTags,f=e.scriptTags,p={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var m=function(e){var t=e.linkTags,n=e.scriptTags,r=e.encode,a=P(e.metaTags,v),o=P(t,y),i=P(n,b);return{priorityMethods:{toComponent:function(){return[].concat(F(g.META,a.priority),F(g.LINK,o.priority),F(g.SCRIPT,i.priority))},toString:function(){return I(g.META,a.priority,r)+" "+I(g.LINK,o.priority,r)+" "+I(g.SCRIPT,i.priority,r)}},metaTags:a.default,linkTags:o.default,scriptTags:i.default}}(e);p=m.priorityMethods,c=m.linkTags,d=m.metaTags,f=m.scriptTags}return{priority:p,base:I(g.BASE,t,r),bodyAttributes:I("bodyAttributes",n,r),htmlAttributes:I("htmlAttributes",a,r),link:I(g.LINK,c,r),meta:I(g.META,d,r),noscript:I(g.NOSCRIPT,o,r),script:I(g.SCRIPT,f,r),style:I(g.STYLE,i,r),title:I(g.TITLE,{title:s,titleAttributes:u},r)}},z=[],$=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?z:n.instances},add:function(e){(n.canUseDOM?z:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?z:n.instances).indexOf(e);(n.canUseDOM?z:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=B({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},U=r.createContext({}),q=o().shape({setHelmet:o().func,helmetInstances:o().shape({get:o().func,add:o().func,remove:o().func})}),H="undefined"!=typeof document,G=function(e){function t(n){var r;return(r=e.call(this,n)||this).helmetData=new $(r.props.context,t.canUseDOM),r}return p(t,e),t.prototype.render=function(){return r.createElement(U.Provider,{value:this.helmetData.value},this.props.children)},t}(r.Component);G.canUseDOM=H,G.propTypes={context:o().shape({helmet:o().shape()}),children:o().node.isRequired},G.defaultProps={context:{}},G.displayName="HelmetProvider";var V=function(e,t){var n,r=document.head||document.querySelector(g.HEAD),a=r.querySelectorAll(e+"[data-rh]"),o=[].slice.call(a),i=[];return t&&t.length&&t.forEach((function(t){var r=document.createElement(e);for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&("innerHTML"===a?r.innerHTML=t.innerHTML:"cssText"===a?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(a,void 0===t[a]?"":t[a]));r.setAttribute("data-rh","true"),o.some((function(e,t){return n=t,r.isEqualNode(e)}))?o.splice(n,1):i.push(r)})),o.forEach((function(e){return e.parentNode.removeChild(e)})),i.forEach((function(e){return r.appendChild(e)})),{oldTags:o,newTags:i}},W=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),a=r?r.split(","):[],o=[].concat(a),i=Object.keys(t),l=0;l<i.length;l+=1){var s=i[l],u=t[s]||"";n.getAttribute(s)!==u&&n.setAttribute(s,u),-1===a.indexOf(s)&&a.push(s);var c=o.indexOf(s);-1!==c&&o.splice(c,1)}for(var d=o.length-1;d>=0;d-=1)n.removeAttribute(o[d]);a.length===o.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==i.join(",")&&n.setAttribute("data-rh",i.join(","))}},Q=function(e,t){var n=e.baseTag,r=e.htmlAttributes,a=e.linkTags,o=e.metaTags,i=e.noscriptTags,l=e.onChangeClientState,s=e.scriptTags,u=e.styleTags,c=e.title,d=e.titleAttributes;W(g.BODY,e.bodyAttributes),W(g.HTML,r),function(e,t){void 0!==e&&document.title!==e&&(document.title=j(e)),W(g.TITLE,t)}(c,d);var f={baseTag:V(g.BASE,n),linkTags:V(g.LINK,a),metaTags:V(g.META,o),noscriptTags:V(g.NOSCRIPT,i),scriptTags:V(g.SCRIPT,s),styleTags:V(g.STYLE,u)},p={},m={};Object.keys(f).forEach((function(e){var t=f[e],n=t.newTags,r=t.oldTags;n.length&&(p[e]=n),r.length&&(m[e]=f[e].oldTags)})),t&&t(),l(e,p,m)},K=null,Y=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(t=e.call.apply(e,[this].concat(r))||this).rendered=!1,t}p(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!d()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,r=n.setHelmet,a=null,o=(e=n.helmetInstances.get().map((function(e){var t=f({},e.props);return delete t.context,t})),{baseTag:A(["href"],e),bodyAttributes:C("bodyAttributes",e),defer:x(e,"defer"),encode:x(e,"encodeSpecialCharacters"),htmlAttributes:C("htmlAttributes",e),linkTags:T(g.LINK,["rel","href"],e),metaTags:T(g.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:T(g.NOSCRIPT,["innerHTML"],e),onChangeClientState:E(e),scriptTags:T(g.SCRIPT,["src","innerHTML"],e),styleTags:T(g.STYLE,["cssText"],e),title:_(e),titleAttributes:C("titleAttributes",e),prioritizeSeoTags:L(e,"prioritizeSeoTags")});G.canUseDOM?(t=o,K&&cancelAnimationFrame(K),t.defer?K=requestAnimationFrame((function(){Q(t,(function(){K=null}))})):(Q(t),K=null)):B&&(a=B(o)),r(a)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(r.Component);Y.propTypes={context:q.isRequired},Y.displayName="HelmetDispatcher";var X=["children"],Z=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}p(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!l()(N(this.props,"helmetData"),N(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case g.SCRIPT:case g.NOSCRIPT:return{innerHTML:t};case g.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return f({},r,((t={})[n.type]=[].concat(r[n.type]||[],[f({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,a=e.newProps,o=e.newChildProps,i=e.nestedChildren;switch(r.type){case g.TITLE:return f({},a,((t={})[r.type]=i,t.titleAttributes=f({},o),t));case g.BODY:return f({},a,{bodyAttributes:f({},o)});case g.HTML:return f({},a,{htmlAttributes:f({},o)});default:return f({},a,((n={})[r.type]=f({},o),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=f({},t);return Object.keys(e).forEach((function(t){var r;n=f({},n,((r={})[t]=e[t],r))})),n},n.warnOnInvalidChildren=function(e,t){return u()(w.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+w.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),u()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,a={};return r.Children.forEach(e,(function(e){if(e&&e.props){var r=e.props,o=r.children,i=h(r,X),l=Object.keys(i).reduce((function(e,t){return e[S[t]||t]=i[t],e}),{}),s=e.type;switch("symbol"==typeof s?s=s.toString():n.warnOnInvalidChildren(e,o),s){case g.FRAGMENT:t=n.mapChildrenToProps(o,t);break;case g.LINK:case g.META:case g.NOSCRIPT:case g.SCRIPT:case g.STYLE:a=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:a,newChildProps:l,nestedChildren:o});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:l,nestedChildren:o})}}})),this.mapArrayTypeChildrenToProps(a,t)},n.render=function(){var e=this.props,t=e.children,n=h(e,Z),a=f({},n),o=n.helmetData;return t&&(a=this.mapChildrenToProps(t,a)),!o||o instanceof $||(o=new $(o.context,o.instances)),o?r.createElement(Y,f({},a,{context:o.value,helmetData:void 0})):r.createElement(U.Consumer,null,(function(e){return r.createElement(Y,f({},a,{context:e}))}))},t}(r.Component);J.propTypes={base:o().object,bodyAttributes:o().object,children:o().oneOfType([o().arrayOf(o().node),o().node]),defaultTitle:o().string,defer:o().bool,encodeSpecialCharacters:o().bool,htmlAttributes:o().object,link:o().arrayOf(o().object),meta:o().arrayOf(o().object),noscript:o().arrayOf(o().object),onChangeClientState:o().func,script:o().arrayOf(o().object),style:o().arrayOf(o().object),title:o().string,titleAttributes:o().object,titleTemplate:o().string,prioritizeSeoTags:o().bool,helmetData:o().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},609:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,t:()=>u});var r=n(6540),a=n(9532),o=n(4848);const i=Symbol("EmptyContext"),l=r.createContext(i);function s({children:e,name:t,items:n}){const a=(0,r.useMemo)((()=>t&&n?{name:t,items:n}:null),[t,n]);return(0,o.jsx)(l.Provider,{value:a,children:e})}function u(){const e=(0,r.useContext)(l);if(e===i)throw new a.dV("DocsSidebarProvider");return e}},679:(e,t,n)=>{"use strict";n.d(t,{Wf:()=>u});n(6540);const r=JSON.parse('{"N":"localStorage","M":""}'),a=r.N;function o({key:e,oldValue:t,newValue:n,storage:r}){if(t===n)return;const a=document.createEvent("StorageEvent");a.initStorageEvent("storage",!1,!1,e,t,n,window.location.href,r),window.dispatchEvent(a)}function i(e=a){if("undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,l||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),l=!0),null}var t}let l=!1;const s={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function u(e,t){const n=`${e}${r.M}`;if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(n);const a=i(t?.persistence);return null===a?s:{get:()=>{try{return a.getItem(n)}catch(e){return console.error(`Docusaurus storage error, can't get key=${n}`,e),null}},set:e=>{try{const t=a.getItem(n);a.setItem(n,e),o({key:n,oldValue:t,newValue:e,storage:a})}catch(t){console.error(`Docusaurus storage error, can't set ${n}=${e}`,t)}},del:()=>{try{const e=a.getItem(n);a.removeItem(n),o({key:n,oldValue:e,newValue:null,storage:a})}catch(e){console.error(`Docusaurus storage error, can't delete key=${n}`,e)}},listen:e=>{try{const t=t=>{t.storageArea===a&&t.key===n&&e(t)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)}catch(t){return console.error(`Docusaurus storage error, can't listen for changes of key=${n}`,t),()=>{}}}}}},961:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(6221)},1043:(e,t,n)=>{"use strict";n.r(t)},1107:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});n(6540);var r=n(4164),a=n(1312),o=n(6342),i=n(8774),l=n(3427);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var u=n(4848);function c({as:e,id:t,...n}){const c=(0,l.A)(),{navbar:{hideOnScroll:d}}=(0,o.p)();if("h1"===e||!t)return(0,u.jsx)(e,{...n,id:void 0});c.collectAnchor(t);const f=(0,a.T)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof n.children?n.children:t});return(0,u.jsxs)(e,{...n,className:(0,r.A)("anchor",d?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,n.className),id:t,children:[n.children,(0,u.jsx)(i.A,{className:"hash-link",to:`#${t}`,"aria-label":f,title:f,children:"\u200b"})]})}},1122:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});var r=n(6540),a=n(4164),o=n(2303),i=n(5293);const l={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var s=n(4848);function u({className:e,children:t}){const n=(0,o.A)(),{colorMode:u}=(0,i.G)();return(0,s.jsx)(s.Fragment,{children:(n?"dark"===u?["dark"]:["light"]:["light","dark"]).map((n=>{const o=t({theme:n,className:(0,a.A)(e,l.themedComponent,l[`themedComponent--${n}`])});return(0,s.jsx)(r.Fragment,{children:o},n)}))})}function c(e){const{sources:t,className:n,alt:r,...a}=e;return(0,s.jsx)(u,{className:n,children:({theme:e,className:n})=>(0,s.jsx)("img",{src:t[e],alt:r,className:n,...a})})}},1247:(e,t,n)=>{"use strict";var r=n(9982),a=n(6540),o=n(961);function i(e){var t="https://react.dev/errors/"+e;if(1<arguments.length){t+="?args[]="+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n])}return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}function l(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType)}function s(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{!!(4098&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function u(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function c(e){if(s(e)!==e)throw Error(i(188))}function d(e){var t=e.tag;if(5===t||26===t||27===t||6===t)return e;for(e=e.child;null!==e;){if(null!==(t=d(e)))return t;e=e.sibling}return null}var f=Object.assign,p=Symbol.for("react.element"),m=Symbol.for("react.transitional.element"),h=Symbol.for("react.portal"),g=Symbol.for("react.fragment"),y=Symbol.for("react.strict_mode"),b=Symbol.for("react.profiler"),v=Symbol.for("react.provider"),w=Symbol.for("react.consumer"),k=Symbol.for("react.context"),S=Symbol.for("react.forward_ref"),x=Symbol.for("react.suspense"),_=Symbol.for("react.suspense_list"),E=Symbol.for("react.memo"),C=Symbol.for("react.lazy");Symbol.for("react.scope");var A=Symbol.for("react.activity");Symbol.for("react.legacy_hidden"),Symbol.for("react.tracing_marker");var T=Symbol.for("react.memo_cache_sentinel");Symbol.for("react.view_transition");var L=Symbol.iterator;function j(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=L&&e[L]||e["@@iterator"])?e:null}var P=Symbol.for("react.client.reference");function N(e){if(null==e)return null;if("function"==typeof e)return e.$$typeof===P?null:e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case g:return"Fragment";case b:return"Profiler";case y:return"StrictMode";case x:return"Suspense";case _:return"SuspenseList";case A:return"Activity"}if("object"==typeof e)switch(e.$$typeof){case h:return"Portal";case k:return(e.displayName||"Context")+".Provider";case w:return(e._context.displayName||"Context")+".Consumer";case S:var t=e.render;return(e=e.displayName)||(e=""!==(e=t.displayName||t.name||"")?"ForwardRef("+e+")":"ForwardRef"),e;case E:return null!==(t=e.displayName||null)?t:N(e.type)||"Memo";case C:t=e._payload,e=e._init;try{return N(e(t))}catch(n){}}return null}var O=Array.isArray,R=a.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,M=o.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,D={pending:!1,data:null,method:null,action:null},F=[],I=-1;function B(e){return{current:e}}function z(e){0>I||(e.current=F[I],F[I]=null,I--)}function $(e,t){I++,F[I]=e.current,e.current=t}var U=B(null),q=B(null),H=B(null),G=B(null);function V(e,t){switch($(H,t),$(q,e),$(U,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?ad(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)e=od(t=ad(t),e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}z(U),$(U,e)}function W(){z(U),z(q),z(H)}function Q(e){null!==e.memoizedState&&$(G,e);var t=U.current,n=od(t,e.type);t!==n&&($(q,e),$(U,n))}function K(e){q.current===e&&(z(U),z(q)),G.current===e&&(z(G),Qd._currentValue=D)}var Y=Object.prototype.hasOwnProperty,X=r.unstable_scheduleCallback,Z=r.unstable_cancelCallback,J=r.unstable_shouldYield,ee=r.unstable_requestPaint,te=r.unstable_now,ne=r.unstable_getCurrentPriorityLevel,re=r.unstable_ImmediatePriority,ae=r.unstable_UserBlockingPriority,oe=r.unstable_NormalPriority,ie=r.unstable_LowPriority,le=r.unstable_IdlePriority,se=r.log,ue=r.unstable_setDisableYieldValue,ce=null,de=null;function fe(e){if("function"==typeof se&&ue(e),de&&"function"==typeof de.setStrictMode)try{de.setStrictMode(ce,e)}catch(t){}}var pe=Math.clz32?Math.clz32:function(e){return 0===(e>>>=0)?32:31-(me(e)/he|0)|0},me=Math.log,he=Math.LN2;var ge=256,ye=4194304;function be(e){var t=42&e;if(0!==t)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return 4194048&e;case 4194304:case 8388608:case 16777216:case 33554432:return 62914560&e;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function ve(e,t,n){var r=e.pendingLanes;if(0===r)return 0;var a=0,o=e.suspendedLanes,i=e.pingedLanes;e=e.warmLanes;var l=134217727&r;return 0!==l?0!==(r=l&~o)?a=be(r):0!==(i&=l)?a=be(i):n||0!==(n=l&~e)&&(a=be(n)):0!==(l=r&~o)?a=be(l):0!==i?a=be(i):n||0!==(n=r&~e)&&(a=be(n)),0===a?0:0!==t&&t!==a&&0===(t&o)&&((o=a&-a)>=(n=t&-t)||32===o&&4194048&n)?t:a}function we(e,t){return 0===(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)}function ke(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;default:return-1}}function Se(){var e=ge;return!(4194048&(ge<<=1))&&(ge=256),e}function xe(){var e=ye;return!(62914560&(ye<<=1))&&(ye=4194304),e}function _e(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Ee(e,t){e.pendingLanes|=t,268435456!==t&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Ce(e,t,n){e.pendingLanes|=t,e.suspendedLanes&=~t;var r=31-pe(t);e.entangledLanes|=t,e.entanglements[r]=1073741824|e.entanglements[r]|4194090&n}function Ae(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var r=31-pe(n),a=1<<r;a&t|e[r]&t&&(e[r]|=t),n&=~a}}function Te(e){switch(e){case 2:e=1;break;case 8:e=4;break;case 32:e=16;break;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:e=128;break;case 268435456:e=134217728;break;default:e=0}return e}function Le(e){return 2<(e&=-e)?8<e?134217727&e?32:268435456:8:2}function je(){var e=M.p;return 0!==e?e:void 0===(e=window.event)?32:cf(e.type)}var Pe=Math.random().toString(36).slice(2),Ne="__reactFiber$"+Pe,Oe="__reactProps$"+Pe,Re="__reactContainer$"+Pe,Me="__reactEvents$"+Pe,De="__reactListeners$"+Pe,Fe="__reactHandles$"+Pe,Ie="__reactResources$"+Pe,Be="__reactMarker$"+Pe;function ze(e){delete e[Ne],delete e[Oe],delete e[Me],delete e[De],delete e[Fe]}function $e(e){var t=e[Ne];if(t)return t;for(var n=e.parentNode;n;){if(t=n[Re]||n[Ne]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=vd(e);null!==e;){if(n=e[Ne])return n;e=vd(e)}return t}n=(e=n).parentNode}return null}function Ue(e){if(e=e[Ne]||e[Re]){var t=e.tag;if(5===t||6===t||13===t||26===t||27===t||3===t)return e}return null}function qe(e){var t=e.tag;if(5===t||26===t||27===t||6===t)return e.stateNode;throw Error(i(33))}function He(e){var t=e[Ie];return t||(t=e[Ie]={hoistableStyles:new Map,hoistableScripts:new Map}),t}function Ge(e){e[Be]=!0}var Ve=new Set,We={};function Qe(e,t){Ke(e,t),Ke(e+"Capture",t)}function Ke(e,t){for(We[e]=t,e=0;e<t.length;e++)Ve.add(t[e])}var Ye,Xe,Ze=RegExp("^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$"),Je={},et={};function tt(e,t,n){if(a=t,Y.call(et,a)||!Y.call(Je,a)&&(Ze.test(a)?et[a]=!0:(Je[a]=!0,0)))if(null===n)e.removeAttribute(t);else{switch(typeof n){case"undefined":case"function":case"symbol":return void e.removeAttribute(t);case"boolean":var r=t.toLowerCase().slice(0,5);if("data-"!==r&&"aria-"!==r)return void e.removeAttribute(t)}e.setAttribute(t,""+n)}var a}function nt(e,t,n){if(null===n)e.removeAttribute(t);else{switch(typeof n){case"undefined":case"function":case"symbol":case"boolean":return void e.removeAttribute(t)}e.setAttribute(t,""+n)}}function rt(e,t,n,r){if(null===r)e.removeAttribute(n);else{switch(typeof r){case"undefined":case"function":case"symbol":case"boolean":return void e.removeAttribute(n)}e.setAttributeNS(t,n,""+r)}}function at(e){if(void 0===Ye)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);Ye=t&&t[1]||"",Xe=-1<n.stack.indexOf("\n at")?" (<anonymous>)":-1<n.stack.indexOf("@")?"@unknown:0:0":""}return"\n"+Ye+e+Xe}var ot=!1;function it(e,t){if(!e||ot)return"";ot=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var r={DetermineComponentFrameRoot:function(){try{if(t){var n=function(){throw Error()};if(Object.defineProperty(n.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(n,[])}catch(a){var r=a}Reflect.construct(e,[],n)}else{try{n.call()}catch(o){r=o}e.call(n.prototype)}}else{try{throw Error()}catch(i){r=i}(n=e())&&"function"==typeof n.catch&&n.catch((function(){}))}}catch(l){if(l&&r&&"string"==typeof l.stack)return[l.stack,r.stack]}return[null,null]}};r.DetermineComponentFrameRoot.displayName="DetermineComponentFrameRoot";var a=Object.getOwnPropertyDescriptor(r.DetermineComponentFrameRoot,"name");a&&a.configurable&&Object.defineProperty(r.DetermineComponentFrameRoot,"name",{value:"DetermineComponentFrameRoot"});var o=r.DetermineComponentFrameRoot(),i=o[0],l=o[1];if(i&&l){var s=i.split("\n"),u=l.split("\n");for(a=r=0;r<s.length&&!s[r].includes("DetermineComponentFrameRoot");)r++;for(;a<u.length&&!u[a].includes("DetermineComponentFrameRoot");)a++;if(r===s.length||a===u.length)for(r=s.length-1,a=u.length-1;1<=r&&0<=a&&s[r]!==u[a];)a--;for(;1<=r&&0<=a;r--,a--)if(s[r]!==u[a]){if(1!==r||1!==a)do{if(r--,0>--a||s[r]!==u[a]){var c="\n"+s[r].replace(" at new "," at ");return e.displayName&&c.includes("<anonymous>")&&(c=c.replace("<anonymous>",e.displayName)),c}}while(1<=r&&0<=a);break}}}finally{ot=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:"")?at(n):""}function lt(e){switch(e.tag){case 26:case 27:case 5:return at(e.type);case 16:return at("Lazy");case 13:return at("Suspense");case 19:return at("SuspenseList");case 0:case 15:return it(e.type,!1);case 11:return it(e.type.render,!1);case 1:return it(e.type,!0);case 31:return at("Activity");default:return""}}function st(e){try{var t="";do{t+=lt(e),e=e.return}while(e);return t}catch(n){return"\nError generating stack: "+n.message+"\n"+n.stack}}function ut(e){switch(typeof e){case"bigint":case"boolean":case"number":case"string":case"undefined":case"object":return e;default:return""}}function ct(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function dt(e){e._valueTracker||(e._valueTracker=function(e){var t=ct(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var a=n.get,o=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return a.call(this)},set:function(e){r=""+e,o.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function ft(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=ct(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function pt(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}var mt=/[\n"\\]/g;function ht(e){return e.replace(mt,(function(e){return"\\"+e.charCodeAt(0).toString(16)+" "}))}function gt(e,t,n,r,a,o,i,l){e.name="",null!=i&&"function"!=typeof i&&"symbol"!=typeof i&&"boolean"!=typeof i?e.type=i:e.removeAttribute("type"),null!=t?"number"===i?(0===t&&""===e.value||e.value!=t)&&(e.value=""+ut(t)):e.value!==""+ut(t)&&(e.value=""+ut(t)):"submit"!==i&&"reset"!==i||e.removeAttribute("value"),null!=t?bt(e,i,ut(t)):null!=n?bt(e,i,ut(n)):null!=r&&e.removeAttribute("value"),null==a&&null!=o&&(e.defaultChecked=!!o),null!=a&&(e.checked=a&&"function"!=typeof a&&"symbol"!=typeof a),null!=l&&"function"!=typeof l&&"symbol"!=typeof l&&"boolean"!=typeof l?e.name=""+ut(l):e.removeAttribute("name")}function yt(e,t,n,r,a,o,i,l){if(null!=o&&"function"!=typeof o&&"symbol"!=typeof o&&"boolean"!=typeof o&&(e.type=o),null!=t||null!=n){if(("submit"===o||"reset"===o)&&null==t)return;n=null!=n?""+ut(n):"",t=null!=t?""+ut(t):n,l||t===e.value||(e.value=t),e.defaultValue=t}r="function"!=typeof(r=null!=r?r:a)&&"symbol"!=typeof r&&!!r,e.checked=l?e.checked:!!r,e.defaultChecked=!!r,null!=i&&"function"!=typeof i&&"symbol"!=typeof i&&"boolean"!=typeof i&&(e.name=i)}function bt(e,t,n){"number"===t&&pt(e.ownerDocument)===e||e.defaultValue===""+n||(e.defaultValue=""+n)}function vt(e,t,n,r){if(e=e.options,t){t={};for(var a=0;a<n.length;a++)t["$"+n[a]]=!0;for(n=0;n<e.length;n++)a=t.hasOwnProperty("$"+e[n].value),e[n].selected!==a&&(e[n].selected=a),a&&r&&(e[n].defaultSelected=!0)}else{for(n=""+ut(n),t=null,a=0;a<e.length;a++){if(e[a].value===n)return e[a].selected=!0,void(r&&(e[a].defaultSelected=!0));null!==t||e[a].disabled||(t=e[a])}null!==t&&(t.selected=!0)}}function wt(e,t,n){null==t||((t=""+ut(t))!==e.value&&(e.value=t),null!=n)?e.defaultValue=null!=n?""+ut(n):"":e.defaultValue!==t&&(e.defaultValue=t)}function kt(e,t,n,r){if(null==t){if(null!=r){if(null!=n)throw Error(i(92));if(O(r)){if(1<r.length)throw Error(i(93));r=r[0]}n=r}null==n&&(n=""),t=n}n=ut(t),e.defaultValue=n,(r=e.textContent)===n&&""!==r&&null!==r&&(e.value=r)}function St(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var xt=new Set("animationIterationCount aspectRatio borderImageOutset borderImageSlice borderImageWidth boxFlex boxFlexGroup boxOrdinalGroup columnCount columns flex flexGrow flexPositive flexShrink flexNegative flexOrder gridArea gridRow gridRowEnd gridRowSpan gridRowStart gridColumn gridColumnEnd gridColumnSpan gridColumnStart fontWeight lineClamp lineHeight opacity order orphans scale tabSize widows zIndex zoom fillOpacity floodOpacity stopOpacity strokeDasharray strokeDashoffset strokeMiterlimit strokeOpacity strokeWidth MozAnimationIterationCount MozBoxFlex MozBoxFlexGroup MozLineClamp msAnimationIterationCount msFlex msZoom msFlexGrow msFlexNegative msFlexOrder msFlexPositive msFlexShrink msGridColumn msGridColumnSpan msGridRow msGridRowSpan WebkitAnimationIterationCount WebkitBoxFlex WebKitBoxFlexGroup WebkitBoxOrdinalGroup WebkitColumnCount WebkitColumns WebkitFlex WebkitFlexGrow WebkitFlexPositive WebkitFlexShrink WebkitLineClamp".split(" "));function _t(e,t,n){var r=0===t.indexOf("--");null==n||"boolean"==typeof n||""===n?r?e.setProperty(t,""):"float"===t?e.cssFloat="":e[t]="":r?e.setProperty(t,n):"number"!=typeof n||0===n||xt.has(t)?"float"===t?e.cssFloat=n:e[t]=(""+n).trim():e[t]=n+"px"}function Et(e,t,n){if(null!=t&&"object"!=typeof t)throw Error(i(62));if(e=e.style,null!=n){for(var r in n)!n.hasOwnProperty(r)||null!=t&&t.hasOwnProperty(r)||(0===r.indexOf("--")?e.setProperty(r,""):"float"===r?e.cssFloat="":e[r]="");for(var a in t)r=t[a],t.hasOwnProperty(a)&&n[a]!==r&&_t(e,a,r)}else for(var o in t)t.hasOwnProperty(o)&&_t(e,o,t[o])}function Ct(e){if(-1===e.indexOf("-"))return!1;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var At=new Map([["acceptCharset","accept-charset"],["htmlFor","for"],["httpEquiv","http-equiv"],["crossOrigin","crossorigin"],["accentHeight","accent-height"],["alignmentBaseline","alignment-baseline"],["arabicForm","arabic-form"],["baselineShift","baseline-shift"],["capHeight","cap-height"],["clipPath","clip-path"],["clipRule","clip-rule"],["colorInterpolation","color-interpolation"],["colorInterpolationFilters","color-interpolation-filters"],["colorProfile","color-profile"],["colorRendering","color-rendering"],["dominantBaseline","dominant-baseline"],["enableBackground","enable-background"],["fillOpacity","fill-opacity"],["fillRule","fill-rule"],["floodColor","flood-color"],["floodOpacity","flood-opacity"],["fontFamily","font-family"],["fontSize","font-size"],["fontSizeAdjust","font-size-adjust"],["fontStretch","font-stretch"],["fontStyle","font-style"],["fontVariant","font-variant"],["fontWeight","font-weight"],["glyphName","glyph-name"],["glyphOrientationHorizontal","glyph-orientation-horizontal"],["glyphOrientationVertical","glyph-orientation-vertical"],["horizAdvX","horiz-adv-x"],["horizOriginX","horiz-origin-x"],["imageRendering","image-rendering"],["letterSpacing","letter-spacing"],["lightingColor","lighting-color"],["markerEnd","marker-end"],["markerMid","marker-mid"],["markerStart","marker-start"],["overlinePosition","overline-position"],["overlineThickness","overline-thickness"],["paintOrder","paint-order"],["panose-1","panose-1"],["pointerEvents","pointer-events"],["renderingIntent","rendering-intent"],["shapeRendering","shape-rendering"],["stopColor","stop-color"],["stopOpacity","stop-opacity"],["strikethroughPosition","strikethrough-position"],["strikethroughThickness","strikethrough-thickness"],["strokeDasharray","stroke-dasharray"],["strokeDashoffset","stroke-dashoffset"],["strokeLinecap","stroke-linecap"],["strokeLinejoin","stroke-linejoin"],["strokeMiterlimit","stroke-miterlimit"],["strokeOpacity","stroke-opacity"],["strokeWidth","stroke-width"],["textAnchor","text-anchor"],["textDecoration","text-decoration"],["textRendering","text-rendering"],["transformOrigin","transform-origin"],["underlinePosition","underline-position"],["underlineThickness","underline-thickness"],["unicodeBidi","unicode-bidi"],["unicodeRange","unicode-range"],["unitsPerEm","units-per-em"],["vAlphabetic","v-alphabetic"],["vHanging","v-hanging"],["vIdeographic","v-ideographic"],["vMathematical","v-mathematical"],["vectorEffect","vector-effect"],["vertAdvY","vert-adv-y"],["vertOriginX","vert-origin-x"],["vertOriginY","vert-origin-y"],["wordSpacing","word-spacing"],["writingMode","writing-mode"],["xmlnsXlink","xmlns:xlink"],["xHeight","x-height"]]),Tt=/^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*:/i;function Lt(e){return Tt.test(""+e)?"javascript:throw new Error('React has blocked a javascript: URL as a security precaution.')":e}var jt=null;function Pt(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var Nt=null,Ot=null;function Rt(e){var t=Ue(e);if(t&&(e=t.stateNode)){var n=e[Oe]||null;e:switch(e=t.stateNode,t.type){case"input":if(gt(e,n.value,n.defaultValue,n.defaultValue,n.checked,n.defaultChecked,n.type,n.name),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll('input[name="'+ht(""+t)+'"][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var a=r[Oe]||null;if(!a)throw Error(i(90));gt(r,a.value,a.defaultValue,a.defaultValue,a.checked,a.defaultChecked,a.type,a.name)}}for(t=0;t<n.length;t++)(r=n[t]).form===e.form&&ft(r)}break e;case"textarea":wt(e,n.value,n.defaultValue);break e;case"select":null!=(t=n.value)&&vt(e,!!n.multiple,t,!1)}}}var Mt=!1;function Dt(e,t,n){if(Mt)return e(t,n);Mt=!0;try{return e(t)}finally{if(Mt=!1,(null!==Nt||null!==Ot)&&($u(),Nt&&(t=Nt,e=Ot,Ot=Nt=null,Rt(t),e)))for(t=0;t<e.length;t++)Rt(e[t])}}function Ft(e,t){var n=e.stateNode;if(null===n)return null;var r=n[Oe]||null;if(null===r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(i(231,t,typeof n));return n}var It=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),Bt=!1;if(It)try{var zt={};Object.defineProperty(zt,"passive",{get:function(){Bt=!0}}),window.addEventListener("test",zt,zt),window.removeEventListener("test",zt,zt)}catch(Rf){Bt=!1}var $t=null,Ut=null,qt=null;function Ht(){if(qt)return qt;var e,t,n=Ut,r=n.length,a="value"in $t?$t.value:$t.textContent,o=a.length;for(e=0;e<r&&n[e]===a[e];e++);var i=r-e;for(t=1;t<=i&&n[r-t]===a[o-t];t++);return qt=a.slice(e,1<t?1-t:void 0)}function Gt(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function Vt(){return!0}function Wt(){return!1}function Qt(e){function t(t,n,r,a,o){for(var i in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=a,this.target=o,this.currentTarget=null,e)e.hasOwnProperty(i)&&(t=e[i],this[i]=t?t(a):a[i]);return this.isDefaultPrevented=(null!=a.defaultPrevented?a.defaultPrevented:!1===a.returnValue)?Vt:Wt,this.isPropagationStopped=Wt,this}return f(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=Vt)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=Vt)},persist:function(){},isPersistent:Vt}),t}var Kt,Yt,Xt,Zt={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},Jt=Qt(Zt),en=f({},Zt,{view:0,detail:0}),tn=Qt(en),nn=f({},en,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:mn,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==Xt&&(Xt&&"mousemove"===e.type?(Kt=e.screenX-Xt.screenX,Yt=e.screenY-Xt.screenY):Yt=Kt=0,Xt=e),Kt)},movementY:function(e){return"movementY"in e?e.movementY:Yt}}),rn=Qt(nn),an=Qt(f({},nn,{dataTransfer:0})),on=Qt(f({},en,{relatedTarget:0})),ln=Qt(f({},Zt,{animationName:0,elapsedTime:0,pseudoElement:0})),sn=Qt(f({},Zt,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}})),un=Qt(f({},Zt,{data:0})),cn={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},dn={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},fn={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function pn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=fn[e])&&!!t[e]}function mn(){return pn}var hn=Qt(f({},en,{key:function(e){if(e.key){var t=cn[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=Gt(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?dn[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:mn,charCode:function(e){return"keypress"===e.type?Gt(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?Gt(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}})),gn=Qt(f({},nn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),yn=Qt(f({},en,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:mn})),bn=Qt(f({},Zt,{propertyName:0,elapsedTime:0,pseudoElement:0})),vn=Qt(f({},nn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0})),wn=Qt(f({},Zt,{newState:0,oldState:0})),kn=[9,13,27,32],Sn=It&&"CompositionEvent"in window,xn=null;It&&"documentMode"in document&&(xn=document.documentMode);var _n=It&&"TextEvent"in window&&!xn,En=It&&(!Sn||xn&&8<xn&&11>=xn),Cn=String.fromCharCode(32),An=!1;function Tn(e,t){switch(e){case"keyup":return-1!==kn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Ln(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var jn=!1;var Pn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Nn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Pn[e.type]:"textarea"===t}function On(e,t,n,r){Nt?Ot?Ot.push(r):Ot=[r]:Nt=r,0<(t=Hc(t,"onChange")).length&&(n=new Jt("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Rn=null,Mn=null;function Dn(e){Dc(e,0)}function Fn(e){if(ft(qe(e)))return e}function In(e,t){if("change"===e)return t}var Bn=!1;if(It){var zn;if(It){var $n="oninput"in document;if(!$n){var Un=document.createElement("div");Un.setAttribute("oninput","return;"),$n="function"==typeof Un.oninput}zn=$n}else zn=!1;Bn=zn&&(!document.documentMode||9<document.documentMode)}function qn(){Rn&&(Rn.detachEvent("onpropertychange",Hn),Mn=Rn=null)}function Hn(e){if("value"===e.propertyName&&Fn(Mn)){var t=[];On(t,Mn,e,Pt(e)),Dt(Dn,t)}}function Gn(e,t,n){"focusin"===e?(qn(),Mn=n,(Rn=t).attachEvent("onpropertychange",Hn)):"focusout"===e&&qn()}function Vn(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Fn(Mn)}function Wn(e,t){if("click"===e)return Fn(t)}function Qn(e,t){if("input"===e||"change"===e)return Fn(t)}var Kn="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t};function Yn(e,t){if(Kn(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++){var a=n[r];if(!Y.call(t,a)||!Kn(e[a],t[a]))return!1}return!0}function Xn(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function Zn(e,t){var n,r=Xn(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=Xn(r)}}function Jn(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?Jn(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function er(e){for(var t=pt((e=null!=e&&null!=e.ownerDocument&&null!=e.ownerDocument.defaultView?e.ownerDocument.defaultView:window).document);t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=pt((e=t.contentWindow).document)}return t}function tr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}var nr=It&&"documentMode"in document&&11>=document.documentMode,rr=null,ar=null,or=null,ir=!1;function lr(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;ir||null==rr||rr!==pt(r)||("selectionStart"in(r=rr)&&tr(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},or&&Yn(or,r)||(or=r,0<(r=Hc(ar,"onSelect")).length&&(t=new Jt("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=rr)))}function sr(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var ur={animationend:sr("Animation","AnimationEnd"),animationiteration:sr("Animation","AnimationIteration"),animationstart:sr("Animation","AnimationStart"),transitionrun:sr("Transition","TransitionRun"),transitionstart:sr("Transition","TransitionStart"),transitioncancel:sr("Transition","TransitionCancel"),transitionend:sr("Transition","TransitionEnd")},cr={},dr={};function fr(e){if(cr[e])return cr[e];if(!ur[e])return e;var t,n=ur[e];for(t in n)if(n.hasOwnProperty(t)&&t in dr)return cr[e]=n[t];return e}It&&(dr=document.createElement("div").style,"AnimationEvent"in window||(delete ur.animationend.animation,delete ur.animationiteration.animation,delete ur.animationstart.animation),"TransitionEvent"in window||delete ur.transitionend.transition);var pr=fr("animationend"),mr=fr("animationiteration"),hr=fr("animationstart"),gr=fr("transitionrun"),yr=fr("transitionstart"),br=fr("transitioncancel"),vr=fr("transitionend"),wr=new Map,kr="abort auxClick beforeToggle cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Sr(e,t){wr.set(e,t),Qe(t,[e])}kr.push("scrollEnd");var xr=new WeakMap;function _r(e,t){if("object"==typeof e&&null!==e){var n=xr.get(e);return void 0!==n?n:(t={value:e,source:t,stack:st(t)},xr.set(e,t),t)}return{value:e,source:t,stack:st(t)}}var Er=[],Cr=0,Ar=0;function Tr(){for(var e=Cr,t=Ar=Cr=0;t<e;){var n=Er[t];Er[t++]=null;var r=Er[t];Er[t++]=null;var a=Er[t];Er[t++]=null;var o=Er[t];if(Er[t++]=null,null!==r&&null!==a){var i=r.pending;null===i?a.next=a:(a.next=i.next,i.next=a),r.pending=a}0!==o&&Nr(n,a,o)}}function Lr(e,t,n,r){Er[Cr++]=e,Er[Cr++]=t,Er[Cr++]=n,Er[Cr++]=r,Ar|=r,e.lanes|=r,null!==(e=e.alternate)&&(e.lanes|=r)}function jr(e,t,n,r){return Lr(e,t,n,r),Or(e)}function Pr(e,t){return Lr(e,null,null,t),Or(e)}function Nr(e,t,n){e.lanes|=n;var r=e.alternate;null!==r&&(r.lanes|=n);for(var a=!1,o=e.return;null!==o;)o.childLanes|=n,null!==(r=o.alternate)&&(r.childLanes|=n),22===o.tag&&(null===(e=o.stateNode)||1&e._visibility||(a=!0)),e=o,o=o.return;return 3===e.tag?(o=e.stateNode,a&&null!==t&&(a=31-pe(n),null===(r=(e=o.hiddenUpdates)[a])?e[a]=[t]:r.push(t),t.lane=536870912|n),o):null}function Or(e){if(50<Nu)throw Nu=0,Ou=null,Error(i(185));for(var t=e.return;null!==t;)t=(e=t).return;return 3===e.tag?e.stateNode:null}var Rr={};function Mr(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.refCleanup=this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Dr(e,t,n,r){return new Mr(e,t,n,r)}function Fr(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Ir(e,t){var n=e.alternate;return null===n?((n=Dr(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=65011712&e.flags,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n.refCleanup=e.refCleanup,n}function Br(e,t){e.flags&=65011714;var n=e.alternate;return null===n?(e.childLanes=0,e.lanes=t,e.child=null,e.subtreeFlags=0,e.memoizedProps=null,e.memoizedState=null,e.updateQueue=null,e.dependencies=null,e.stateNode=null):(e.childLanes=n.childLanes,e.lanes=n.lanes,e.child=n.child,e.subtreeFlags=0,e.deletions=null,e.memoizedProps=n.memoizedProps,e.memoizedState=n.memoizedState,e.updateQueue=n.updateQueue,e.type=n.type,t=n.dependencies,e.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext}),e}function zr(e,t,n,r,a,o){var l=0;if(r=e,"function"==typeof e)Fr(e)&&(l=1);else if("string"==typeof e)l=function(e,t,n){if(1===n||null!=t.itemProp)return!1;switch(e){case"meta":case"title":return!0;case"style":if("string"!=typeof t.precedence||"string"!=typeof t.href||""===t.href)break;return!0;case"link":if("string"!=typeof t.rel||"string"!=typeof t.href||""===t.href||t.onLoad||t.onError)break;return"stylesheet"!==t.rel||(e=t.disabled,"string"==typeof t.precedence&&null==e);case"script":if(t.async&&"function"!=typeof t.async&&"symbol"!=typeof t.async&&!t.onLoad&&!t.onError&&t.src&&"string"==typeof t.src)return!0}return!1}(e,n,U.current)?26:"html"===e||"head"===e||"body"===e?27:5;else e:switch(e){case A:return(e=Dr(31,n,t,a)).elementType=A,e.lanes=o,e;case g:return $r(n.children,a,o,t);case y:l=8,a|=24;break;case b:return(e=Dr(12,n,t,2|a)).elementType=b,e.lanes=o,e;case x:return(e=Dr(13,n,t,a)).elementType=x,e.lanes=o,e;case _:return(e=Dr(19,n,t,a)).elementType=_,e.lanes=o,e;default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case v:case k:l=10;break e;case w:l=9;break e;case S:l=11;break e;case E:l=14;break e;case C:l=16,r=null;break e}l=29,n=Error(i(130,null===e?"null":typeof e,"")),r=null}return(t=Dr(l,n,t,a)).elementType=e,t.type=r,t.lanes=o,t}function $r(e,t,n,r){return(e=Dr(7,e,r,t)).lanes=n,e}function Ur(e,t,n){return(e=Dr(6,e,null,t)).lanes=n,e}function qr(e,t,n){return(t=Dr(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}var Hr=[],Gr=0,Vr=null,Wr=0,Qr=[],Kr=0,Yr=null,Xr=1,Zr="";function Jr(e,t){Hr[Gr++]=Wr,Hr[Gr++]=Vr,Vr=e,Wr=t}function ea(e,t,n){Qr[Kr++]=Xr,Qr[Kr++]=Zr,Qr[Kr++]=Yr,Yr=e;var r=Xr;e=Zr;var a=32-pe(r)-1;r&=~(1<<a),n+=1;var o=32-pe(t)+a;if(30<o){var i=a-a%5;o=(r&(1<<i)-1).toString(32),r>>=i,a-=i,Xr=1<<32-pe(t)+a|n<<a|r,Zr=o+e}else Xr=1<<o|n<<a|r,Zr=e}function ta(e){null!==e.return&&(Jr(e,1),ea(e,1,0))}function na(e){for(;e===Vr;)Vr=Hr[--Gr],Hr[Gr]=null,Wr=Hr[--Gr],Hr[Gr]=null;for(;e===Yr;)Yr=Qr[--Kr],Qr[Kr]=null,Zr=Qr[--Kr],Qr[Kr]=null,Xr=Qr[--Kr],Qr[Kr]=null}var ra=null,aa=null,oa=!1,ia=null,la=!1,sa=Error(i(519));function ua(e){throw ha(_r(Error(i(418,"")),e)),sa}function ca(e){var t=e.stateNode,n=e.type,r=e.memoizedProps;switch(t[Ne]=e,t[Oe]=r,n){case"dialog":Fc("cancel",t),Fc("close",t);break;case"iframe":case"object":case"embed":Fc("load",t);break;case"video":case"audio":for(n=0;n<Rc.length;n++)Fc(Rc[n],t);break;case"source":Fc("error",t);break;case"img":case"image":case"link":Fc("error",t),Fc("load",t);break;case"details":Fc("toggle",t);break;case"input":Fc("invalid",t),yt(t,r.value,r.defaultValue,r.checked,r.defaultChecked,r.type,r.name,!0),dt(t);break;case"select":Fc("invalid",t);break;case"textarea":Fc("invalid",t),kt(t,r.value,r.defaultValue,r.children),dt(t)}"string"!=typeof(n=r.children)&&"number"!=typeof n&&"bigint"!=typeof n||t.textContent===""+n||!0===r.suppressHydrationWarning||Yc(t.textContent,n)?(null!=r.popover&&(Fc("beforetoggle",t),Fc("toggle",t)),null!=r.onScroll&&Fc("scroll",t),null!=r.onScrollEnd&&Fc("scrollend",t),null!=r.onClick&&(t.onclick=Xc),t=!0):t=!1,t||ua(e)}function da(e){for(ra=e.return;ra;)switch(ra.tag){case 5:case 13:return void(la=!1);case 27:case 3:return void(la=!0);default:ra=ra.return}}function fa(e){if(e!==ra)return!1;if(!oa)return da(e),oa=!0,!1;var t,n=e.tag;if((t=3!==n&&27!==n)&&((t=5===n)&&(t=!("form"!==(t=e.type)&&"button"!==t)||id(e.type,e.memoizedProps)),t=!t),t&&aa&&ua(e),da(e),13===n){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(i(317));e:{for(e=e.nextSibling,n=0;e;){if(8===e.nodeType)if("/$"===(t=e.data)){if(0===n){aa=yd(e.nextSibling);break e}n--}else"$"!==t&&"$!"!==t&&"$?"!==t||n++;e=e.nextSibling}aa=null}}else 27===n?(n=aa,pd(e.type)?(e=bd,bd=null,aa=e):aa=n):aa=ra?yd(e.stateNode.nextSibling):null;return!0}function pa(){aa=ra=null,oa=!1}function ma(){var e=ia;return null!==e&&(null===vu?vu=e:vu.push.apply(vu,e),ia=null),e}function ha(e){null===ia?ia=[e]:ia.push(e)}var ga=B(null),ya=null,ba=null;function va(e,t,n){$(ga,t._currentValue),t._currentValue=n}function wa(e){e._currentValue=ga.current,z(ga)}function ka(e,t,n){for(;null!==e;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,null!==r&&(r.childLanes|=t)):null!==r&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function Sa(e,t,n,r){var a=e.child;for(null!==a&&(a.return=e);null!==a;){var o=a.dependencies;if(null!==o){var l=a.child;o=o.firstContext;e:for(;null!==o;){var s=o;o=a;for(var u=0;u<t.length;u++)if(s.context===t[u]){o.lanes|=n,null!==(s=o.alternate)&&(s.lanes|=n),ka(o.return,n,e),r||(l=null);break e}o=s.next}}else if(18===a.tag){if(null===(l=a.return))throw Error(i(341));l.lanes|=n,null!==(o=l.alternate)&&(o.lanes|=n),ka(l,n,e),l=null}else l=a.child;if(null!==l)l.return=a;else for(l=a;null!==l;){if(l===e){l=null;break}if(null!==(a=l.sibling)){a.return=l.return,l=a;break}l=l.return}a=l}}function xa(e,t,n,r){e=null;for(var a=t,o=!1;null!==a;){if(!o)if(524288&a.flags)o=!0;else if(262144&a.flags)break;if(10===a.tag){var l=a.alternate;if(null===l)throw Error(i(387));if(null!==(l=l.memoizedProps)){var s=a.type;Kn(a.pendingProps.value,l.value)||(null!==e?e.push(s):e=[s])}}else if(a===G.current){if(null===(l=a.alternate))throw Error(i(387));l.memoizedState.memoizedState!==a.memoizedState.memoizedState&&(null!==e?e.push(Qd):e=[Qd])}a=a.return}null!==e&&Sa(t,e,n,r),t.flags|=262144}function _a(e){for(e=e.firstContext;null!==e;){if(!Kn(e.context._currentValue,e.memoizedValue))return!0;e=e.next}return!1}function Ea(e){ya=e,ba=null,null!==(e=e.dependencies)&&(e.firstContext=null)}function Ca(e){return Ta(ya,e)}function Aa(e,t){return null===ya&&Ea(e),Ta(e,t)}function Ta(e,t){var n=t._currentValue;if(t={context:t,memoizedValue:n,next:null},null===ba){if(null===e)throw Error(i(308));ba=t,e.dependencies={lanes:0,firstContext:t},e.flags|=524288}else ba=ba.next=t;return n}var La="undefined"!=typeof AbortController?AbortController:function(){var e=[],t=this.signal={aborted:!1,addEventListener:function(t,n){e.push(n)}};this.abort=function(){t.aborted=!0,e.forEach((function(e){return e()}))}},ja=r.unstable_scheduleCallback,Pa=r.unstable_NormalPriority,Na={$$typeof:k,Consumer:null,Provider:null,_currentValue:null,_currentValue2:null,_threadCount:0};function Oa(){return{controller:new La,data:new Map,refCount:0}}function Ra(e){e.refCount--,0===e.refCount&&ja(Pa,(function(){e.controller.abort()}))}var Ma=null,Da=0,Fa=0,Ia=null;function Ba(){if(0===--Da&&null!==Ma){null!==Ia&&(Ia.status="fulfilled");var e=Ma;Ma=null,Fa=0,Ia=null;for(var t=0;t<e.length;t++)(0,e[t])()}}var za=R.S;R.S=function(e,t){"object"==typeof t&&null!==t&&"function"==typeof t.then&&function(e,t){if(null===Ma){var n=Ma=[];Da=0,Fa=Lc(),Ia={status:"pending",value:void 0,then:function(e){n.push(e)}}}Da++,t.then(Ba,Ba)}(0,t),null!==za&&za(e,t)};var $a=B(null);function Ua(){var e=$a.current;return null!==e?e:ru.pooledCache}function qa(e,t){$($a,null===t?$a.current:t.pool)}function Ha(){var e=Ua();return null===e?null:{parent:Na._currentValue,pool:e}}var Ga=Error(i(460)),Va=Error(i(474)),Wa=Error(i(542)),Qa={then:function(){}};function Ka(e){return"fulfilled"===(e=e.status)||"rejected"===e}function Ya(){}function Xa(e,t,n){switch(void 0===(n=e[n])?e.push(t):n!==t&&(t.then(Ya,Ya),t=n),t.status){case"fulfilled":return t.value;case"rejected":throw eo(e=t.reason),e;default:if("string"==typeof t.status)t.then(Ya,Ya);else{if(null!==(e=ru)&&100<e.shellSuspendCounter)throw Error(i(482));(e=t).status="pending",e.then((function(e){if("pending"===t.status){var n=t;n.status="fulfilled",n.value=e}}),(function(e){if("pending"===t.status){var n=t;n.status="rejected",n.reason=e}}))}switch(t.status){case"fulfilled":return t.value;case"rejected":throw eo(e=t.reason),e}throw Za=t,Ga}}var Za=null;function Ja(){if(null===Za)throw Error(i(459));var e=Za;return Za=null,e}function eo(e){if(e===Ga||e===Wa)throw Error(i(483))}var to=!1;function no(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function ro(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function ao(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function oo(e,t,n){var r=e.updateQueue;if(null===r)return null;if(r=r.shared,2&nu){var a=r.pending;return null===a?t.next=t:(t.next=a.next,a.next=t),r.pending=t,t=Or(e),Nr(e,null,n),t}return Lr(e,r,t,n),Or(e)}function io(e,t,n){if(null!==(t=t.updateQueue)&&(t=t.shared,4194048&n)){var r=t.lanes;n|=r&=e.pendingLanes,t.lanes=n,Ae(e,n)}}function lo(e,t){var n=e.updateQueue,r=e.alternate;if(null!==r&&n===(r=r.updateQueue)){var a=null,o=null;if(null!==(n=n.firstBaseUpdate)){do{var i={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};null===o?a=o=i:o=o.next=i,n=n.next}while(null!==n);null===o?a=o=t:o=o.next=t}else a=o=t;return n={baseState:r.baseState,firstBaseUpdate:a,lastBaseUpdate:o,shared:r.shared,callbacks:r.callbacks},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var so=!1;function uo(){if(so){if(null!==Ia)throw Ia}}function co(e,t,n,r){so=!1;var a=e.updateQueue;to=!1;var o=a.firstBaseUpdate,i=a.lastBaseUpdate,l=a.shared.pending;if(null!==l){a.shared.pending=null;var s=l,u=s.next;s.next=null,null===i?o=u:i.next=u,i=s;var c=e.alternate;null!==c&&((l=(c=c.updateQueue).lastBaseUpdate)!==i&&(null===l?c.firstBaseUpdate=u:l.next=u,c.lastBaseUpdate=s))}if(null!==o){var d=a.baseState;for(i=0,c=u=s=null,l=o;;){var p=-536870913&l.lane,m=p!==l.lane;if(m?(ou&p)===p:(r&p)===p){0!==p&&p===Fa&&(so=!0),null!==c&&(c=c.next={lane:0,tag:l.tag,payload:l.payload,callback:null,next:null});e:{var h=e,g=l;p=t;var y=n;switch(g.tag){case 1:if("function"==typeof(h=g.payload)){d=h.call(y,d,p);break e}d=h;break e;case 3:h.flags=-65537&h.flags|128;case 0:if(null==(p="function"==typeof(h=g.payload)?h.call(y,d,p):h))break e;d=f({},d,p);break e;case 2:to=!0}}null!==(p=l.callback)&&(e.flags|=64,m&&(e.flags|=8192),null===(m=a.callbacks)?a.callbacks=[p]:m.push(p))}else m={lane:p,tag:l.tag,payload:l.payload,callback:l.callback,next:null},null===c?(u=c=m,s=d):c=c.next=m,i|=p;if(null===(l=l.next)){if(null===(l=a.shared.pending))break;l=(m=l).next,m.next=null,a.lastBaseUpdate=m,a.shared.pending=null}}null===c&&(s=d),a.baseState=s,a.firstBaseUpdate=u,a.lastBaseUpdate=c,null===o&&(a.shared.lanes=0),pu|=i,e.lanes=i,e.memoizedState=d}}function fo(e,t){if("function"!=typeof e)throw Error(i(191,e));e.call(t)}function po(e,t){var n=e.callbacks;if(null!==n)for(e.callbacks=null,e=0;e<n.length;e++)fo(n[e],t)}var mo=B(null),ho=B(0);function go(e,t){$(ho,e=du),$(mo,t),du=e|t.baseLanes}function yo(){$(ho,du),$(mo,mo.current)}function bo(){du=ho.current,z(mo),z(ho)}var vo=0,wo=null,ko=null,So=null,xo=!1,_o=!1,Eo=!1,Co=0,Ao=0,To=null,Lo=0;function jo(){throw Error(i(321))}function Po(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!Kn(e[n],t[n]))return!1;return!0}function No(e,t,n,r,a,o){return vo=o,wo=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,R.H=null===e||null===e.memoizedState?Vi:Wi,Eo=!1,o=n(r,a),Eo=!1,_o&&(o=Ro(t,n,r,a)),Oo(e),o}function Oo(e){R.H=Gi;var t=null!==ko&&null!==ko.next;if(vo=0,So=ko=wo=null,xo=!1,Ao=0,To=null,t)throw Error(i(300));null===e||Al||null!==(e=e.dependencies)&&_a(e)&&(Al=!0)}function Ro(e,t,n,r){wo=e;var a=0;do{if(_o&&(To=null),Ao=0,_o=!1,25<=a)throw Error(i(301));if(a+=1,So=ko=null,null!=e.updateQueue){var o=e.updateQueue;o.lastEffect=null,o.events=null,o.stores=null,null!=o.memoCache&&(o.memoCache.index=0)}R.H=Qi,o=t(n,r)}while(_o);return o}function Mo(){var e=R.H,t=e.useState()[0];return t="function"==typeof t.then?$o(t):t,e=e.useState()[0],(null!==ko?ko.memoizedState:null)!==e&&(wo.flags|=1024),t}function Do(){var e=0!==Co;return Co=0,e}function Fo(e,t,n){t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~n}function Io(e){if(xo){for(e=e.memoizedState;null!==e;){var t=e.queue;null!==t&&(t.pending=null),e=e.next}xo=!1}vo=0,So=ko=wo=null,_o=!1,Ao=Co=0,To=null}function Bo(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===So?wo.memoizedState=So=e:So=So.next=e,So}function zo(){if(null===ko){var e=wo.alternate;e=null!==e?e.memoizedState:null}else e=ko.next;var t=null===So?wo.memoizedState:So.next;if(null!==t)So=t,ko=e;else{if(null===e){if(null===wo.alternate)throw Error(i(467));throw Error(i(310))}e={memoizedState:(ko=e).memoizedState,baseState:ko.baseState,baseQueue:ko.baseQueue,queue:ko.queue,next:null},null===So?wo.memoizedState=So=e:So=So.next=e}return So}function $o(e){var t=Ao;return Ao+=1,null===To&&(To=[]),e=Xa(To,e,t),t=wo,null===(null===So?t.memoizedState:So.next)&&(t=t.alternate,R.H=null===t||null===t.memoizedState?Vi:Wi),e}function Uo(e){if(null!==e&&"object"==typeof e){if("function"==typeof e.then)return $o(e);if(e.$$typeof===k)return Ca(e)}throw Error(i(438,String(e)))}function qo(e){var t=null,n=wo.updateQueue;if(null!==n&&(t=n.memoCache),null==t){var r=wo.alternate;null!==r&&(null!==(r=r.updateQueue)&&(null!=(r=r.memoCache)&&(t={data:r.data.map((function(e){return e.slice()})),index:0})))}if(null==t&&(t={data:[],index:0}),null===n&&(n={lastEffect:null,events:null,stores:null,memoCache:null},wo.updateQueue=n),n.memoCache=t,void 0===(n=t.data[t.index]))for(n=t.data[t.index]=Array(e),r=0;r<e;r++)n[r]=T;return t.index++,n}function Ho(e,t){return"function"==typeof t?t(e):t}function Go(e){return Vo(zo(),ko,e)}function Vo(e,t,n){var r=e.queue;if(null===r)throw Error(i(311));r.lastRenderedReducer=n;var a=e.baseQueue,o=r.pending;if(null!==o){if(null!==a){var l=a.next;a.next=o.next,o.next=l}t.baseQueue=a=o,r.pending=null}if(o=e.baseState,null===a)e.memoizedState=o;else{var s=l=null,u=null,c=t=a.next,d=!1;do{var f=-536870913&c.lane;if(f!==c.lane?(ou&f)===f:(vo&f)===f){var p=c.revertLane;if(0===p)null!==u&&(u=u.next={lane:0,revertLane:0,action:c.action,hasEagerState:c.hasEagerState,eagerState:c.eagerState,next:null}),f===Fa&&(d=!0);else{if((vo&p)===p){c=c.next,p===Fa&&(d=!0);continue}f={lane:0,revertLane:c.revertLane,action:c.action,hasEagerState:c.hasEagerState,eagerState:c.eagerState,next:null},null===u?(s=u=f,l=o):u=u.next=f,wo.lanes|=p,pu|=p}f=c.action,Eo&&n(o,f),o=c.hasEagerState?c.eagerState:n(o,f)}else p={lane:f,revertLane:c.revertLane,action:c.action,hasEagerState:c.hasEagerState,eagerState:c.eagerState,next:null},null===u?(s=u=p,l=o):u=u.next=p,wo.lanes|=f,pu|=f;c=c.next}while(null!==c&&c!==t);if(null===u?l=o:u.next=s,!Kn(o,e.memoizedState)&&(Al=!0,d&&null!==(n=Ia)))throw n;e.memoizedState=o,e.baseState=l,e.baseQueue=u,r.lastRenderedState=o}return null===a&&(r.lanes=0),[e.memoizedState,r.dispatch]}function Wo(e){var t=zo(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=n.dispatch,a=n.pending,o=t.memoizedState;if(null!==a){n.pending=null;var l=a=a.next;do{o=e(o,l.action),l=l.next}while(l!==a);Kn(o,t.memoizedState)||(Al=!0),t.memoizedState=o,null===t.baseQueue&&(t.baseState=o),n.lastRenderedState=o}return[o,r]}function Qo(e,t,n){var r=wo,a=zo(),o=oa;if(o){if(void 0===n)throw Error(i(407));n=n()}else n=t();var l=!Kn((ko||a).memoizedState,n);if(l&&(a.memoizedState=n,Al=!0),a=a.queue,yi(2048,8,Xo.bind(null,r,a,e),[e]),a.getSnapshot!==t||l||null!==So&&1&So.memoizedState.tag){if(r.flags|=2048,mi(9,{destroy:void 0,resource:void 0},Yo.bind(null,r,a,n,t),null),null===ru)throw Error(i(349));o||124&vo||Ko(r,t,n)}return n}function Ko(e,t,n){e.flags|=16384,e={getSnapshot:t,value:n},null===(t=wo.updateQueue)?(t={lastEffect:null,events:null,stores:null,memoCache:null},wo.updateQueue=t,t.stores=[e]):null===(n=t.stores)?t.stores=[e]:n.push(e)}function Yo(e,t,n,r){t.value=n,t.getSnapshot=r,Zo(t)&&Jo(e)}function Xo(e,t,n){return n((function(){Zo(t)&&Jo(e)}))}function Zo(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!Kn(e,n)}catch(r){return!0}}function Jo(e){var t=Pr(e,2);null!==t&&Du(t,e,2)}function ei(e){var t=Bo();if("function"==typeof e){var n=e;if(e=n(),Eo){fe(!0);try{n()}finally{fe(!1)}}}return t.memoizedState=t.baseState=e,t.queue={pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ho,lastRenderedState:e},t}function ti(e,t,n,r){return e.baseState=n,Vo(e,ko,"function"==typeof r?r:Ho)}function ni(e,t,n,r,a){if(Ui(e))throw Error(i(485));if(null!==(e=t.action)){var o={payload:a,action:e,next:null,isTransition:!0,status:"pending",value:null,reason:null,listeners:[],then:function(e){o.listeners.push(e)}};null!==R.T?n(!0):o.isTransition=!1,r(o),null===(n=t.pending)?(o.next=t.pending=o,ri(t,o)):(o.next=n.next,t.pending=n.next=o)}}function ri(e,t){var n=t.action,r=t.payload,a=e.state;if(t.isTransition){var o=R.T,i={};R.T=i;try{var l=n(a,r),s=R.S;null!==s&&s(i,l),ai(e,t,l)}catch(u){ii(e,t,u)}finally{R.T=o}}else try{ai(e,t,o=n(a,r))}catch(c){ii(e,t,c)}}function ai(e,t,n){null!==n&&"object"==typeof n&&"function"==typeof n.then?n.then((function(n){oi(e,t,n)}),(function(n){return ii(e,t,n)})):oi(e,t,n)}function oi(e,t,n){t.status="fulfilled",t.value=n,li(t),e.state=n,null!==(t=e.pending)&&((n=t.next)===t?e.pending=null:(n=n.next,t.next=n,ri(e,n)))}function ii(e,t,n){var r=e.pending;if(e.pending=null,null!==r){r=r.next;do{t.status="rejected",t.reason=n,li(t),t=t.next}while(t!==r)}e.action=null}function li(e){e=e.listeners;for(var t=0;t<e.length;t++)(0,e[t])()}function si(e,t){return t}function ui(e,t){if(oa){var n=ru.formState;if(null!==n){e:{var r=wo;if(oa){if(aa){t:{for(var a=aa,o=la;8!==a.nodeType;){if(!o){a=null;break t}if(null===(a=yd(a.nextSibling))){a=null;break t}}a="F!"===(o=a.data)||"F"===o?a:null}if(a){aa=yd(a.nextSibling),r="F!"===a.data;break e}}ua(r)}r=!1}r&&(t=n[0])}}return(n=Bo()).memoizedState=n.baseState=t,r={pending:null,lanes:0,dispatch:null,lastRenderedReducer:si,lastRenderedState:t},n.queue=r,n=Bi.bind(null,wo,r),r.dispatch=n,r=ei(!1),o=$i.bind(null,wo,!1,r.queue),a={state:t,dispatch:null,action:e,pending:null},(r=Bo()).queue=a,n=ni.bind(null,wo,a,o,n),a.dispatch=n,r.memoizedState=e,[t,n,!1]}function ci(e){return di(zo(),ko,e)}function di(e,t,n){if(t=Vo(e,t,si)[0],e=Go(Ho)[0],"object"==typeof t&&null!==t&&"function"==typeof t.then)try{var r=$o(t)}catch(i){if(i===Ga)throw Wa;throw i}else r=t;var a=(t=zo()).queue,o=a.dispatch;return n!==t.memoizedState&&(wo.flags|=2048,mi(9,{destroy:void 0,resource:void 0},fi.bind(null,a,n),null)),[r,o,e]}function fi(e,t){e.action=t}function pi(e){var t=zo(),n=ko;if(null!==n)return di(t,n,e);zo(),t=t.memoizedState;var r=(n=zo()).queue.dispatch;return n.memoizedState=e,[t,r,!1]}function mi(e,t,n,r){return e={tag:e,create:n,deps:r,inst:t,next:null},null===(t=wo.updateQueue)&&(t={lastEffect:null,events:null,stores:null,memoCache:null},wo.updateQueue=t),null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function hi(){return zo().memoizedState}function gi(e,t,n,r){var a=Bo();r=void 0===r?null:r,wo.flags|=e,a.memoizedState=mi(1|t,{destroy:void 0,resource:void 0},n,r)}function yi(e,t,n,r){var a=zo();r=void 0===r?null:r;var o=a.memoizedState.inst;null!==ko&&null!==r&&Po(r,ko.memoizedState.deps)?a.memoizedState=mi(t,o,n,r):(wo.flags|=e,a.memoizedState=mi(1|t,o,n,r))}function bi(e,t){gi(8390656,8,e,t)}function vi(e,t){yi(2048,8,e,t)}function wi(e,t){return yi(4,2,e,t)}function ki(e,t){return yi(4,4,e,t)}function Si(e,t){if("function"==typeof t){e=e();var n=t(e);return function(){"function"==typeof n?n():t(null)}}if(null!=t)return e=e(),t.current=e,function(){t.current=null}}function xi(e,t,n){n=null!=n?n.concat([e]):null,yi(4,4,Si.bind(null,t,e),n)}function _i(){}function Ei(e,t){var n=zo();t=void 0===t?null:t;var r=n.memoizedState;return null!==t&&Po(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function Ci(e,t){var n=zo();t=void 0===t?null:t;var r=n.memoizedState;if(null!==t&&Po(t,r[1]))return r[0];if(r=e(),Eo){fe(!0);try{e()}finally{fe(!1)}}return n.memoizedState=[r,t],r}function Ai(e,t,n){return void 0===n||1073741824&vo?e.memoizedState=t:(e.memoizedState=n,e=Mu(),wo.lanes|=e,pu|=e,n)}function Ti(e,t,n,r){return Kn(n,t)?n:null!==mo.current?(e=Ai(e,n,r),Kn(e,t)||(Al=!0),e):42&vo?(e=Mu(),wo.lanes|=e,pu|=e,t):(Al=!0,e.memoizedState=n)}function Li(e,t,n,r,a){var o=M.p;M.p=0!==o&&8>o?o:8;var i,l,s,u=R.T,c={};R.T=c,$i(e,!1,t,n);try{var d=a(),f=R.S;if(null!==f&&f(c,d),null!==d&&"object"==typeof d&&"function"==typeof d.then)zi(e,t,(i=r,l=[],s={status:"pending",value:null,reason:null,then:function(e){l.push(e)}},d.then((function(){s.status="fulfilled",s.value=i;for(var e=0;e<l.length;e++)(0,l[e])(i)}),(function(e){for(s.status="rejected",s.reason=e,e=0;e<l.length;e++)(0,l[e])(void 0)})),s),Ru());else zi(e,t,r,Ru())}catch(p){zi(e,t,{then:function(){},status:"rejected",reason:p},Ru())}finally{M.p=o,R.T=u}}function ji(){}function Pi(e,t,n,r){if(5!==e.tag)throw Error(i(476));var a=Ni(e).queue;Li(e,a,t,D,null===n?ji:function(){return Oi(e),n(r)})}function Ni(e){var t=e.memoizedState;if(null!==t)return t;var n={};return(t={memoizedState:D,baseState:D,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ho,lastRenderedState:D},next:null}).next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ho,lastRenderedState:n},next:null},e.memoizedState=t,null!==(e=e.alternate)&&(e.memoizedState=t),t}function Oi(e){zi(e,Ni(e).next.queue,{},Ru())}function Ri(){return Ca(Qd)}function Mi(){return zo().memoizedState}function Di(){return zo().memoizedState}function Fi(e){for(var t=e.return;null!==t;){switch(t.tag){case 24:case 3:var n=Ru(),r=oo(t,e=ao(n),n);return null!==r&&(Du(r,t,n),io(r,t,n)),t={cache:Oa()},void(e.payload=t)}t=t.return}}function Ii(e,t,n){var r=Ru();n={lane:r,revertLane:0,action:n,hasEagerState:!1,eagerState:null,next:null},Ui(e)?qi(t,n):null!==(n=jr(e,t,n,r))&&(Du(n,e,r),Hi(n,t,r))}function Bi(e,t,n){zi(e,t,n,Ru())}function zi(e,t,n,r){var a={lane:r,revertLane:0,action:n,hasEagerState:!1,eagerState:null,next:null};if(Ui(e))qi(t,a);else{var o=e.alternate;if(0===e.lanes&&(null===o||0===o.lanes)&&null!==(o=t.lastRenderedReducer))try{var i=t.lastRenderedState,l=o(i,n);if(a.hasEagerState=!0,a.eagerState=l,Kn(l,i))return Lr(e,t,a,0),null===ru&&Tr(),!1}catch(s){}if(null!==(n=jr(e,t,a,r)))return Du(n,e,r),Hi(n,t,r),!0}return!1}function $i(e,t,n,r){if(r={lane:2,revertLane:Lc(),action:r,hasEagerState:!1,eagerState:null,next:null},Ui(e)){if(t)throw Error(i(479))}else null!==(t=jr(e,n,r,2))&&Du(t,e,2)}function Ui(e){var t=e.alternate;return e===wo||null!==t&&t===wo}function qi(e,t){_o=xo=!0;var n=e.pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Hi(e,t,n){if(4194048&n){var r=t.lanes;n|=r&=e.pendingLanes,t.lanes=n,Ae(e,n)}}var Gi={readContext:Ca,use:Uo,useCallback:jo,useContext:jo,useEffect:jo,useImperativeHandle:jo,useLayoutEffect:jo,useInsertionEffect:jo,useMemo:jo,useReducer:jo,useRef:jo,useState:jo,useDebugValue:jo,useDeferredValue:jo,useTransition:jo,useSyncExternalStore:jo,useId:jo,useHostTransitionStatus:jo,useFormState:jo,useActionState:jo,useOptimistic:jo,useMemoCache:jo,useCacheRefresh:jo},Vi={readContext:Ca,use:Uo,useCallback:function(e,t){return Bo().memoizedState=[e,void 0===t?null:t],e},useContext:Ca,useEffect:bi,useImperativeHandle:function(e,t,n){n=null!=n?n.concat([e]):null,gi(4194308,4,Si.bind(null,t,e),n)},useLayoutEffect:function(e,t){return gi(4194308,4,e,t)},useInsertionEffect:function(e,t){gi(4,2,e,t)},useMemo:function(e,t){var n=Bo();t=void 0===t?null:t;var r=e();if(Eo){fe(!0);try{e()}finally{fe(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=Bo();if(void 0!==n){var a=n(t);if(Eo){fe(!0);try{n(t)}finally{fe(!1)}}}else a=t;return r.memoizedState=r.baseState=a,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:a},r.queue=e,e=e.dispatch=Ii.bind(null,wo,e),[r.memoizedState,e]},useRef:function(e){return e={current:e},Bo().memoizedState=e},useState:function(e){var t=(e=ei(e)).queue,n=Bi.bind(null,wo,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:_i,useDeferredValue:function(e,t){return Ai(Bo(),e,t)},useTransition:function(){var e=ei(!1);return e=Li.bind(null,wo,e.queue,!0,!1),Bo().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=wo,a=Bo();if(oa){if(void 0===n)throw Error(i(407));n=n()}else{if(n=t(),null===ru)throw Error(i(349));124&ou||Ko(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,bi(Xo.bind(null,r,o,e),[e]),r.flags|=2048,mi(9,{destroy:void 0,resource:void 0},Yo.bind(null,r,o,n,t),null),n},useId:function(){var e=Bo(),t=ru.identifierPrefix;if(oa){var n=Zr;t="\xab"+t+"R"+(n=(Xr&~(1<<32-pe(Xr)-1)).toString(32)+n),0<(n=Co++)&&(t+="H"+n.toString(32)),t+="\xbb"}else t="\xab"+t+"r"+(n=Lo++).toString(32)+"\xbb";return e.memoizedState=t},useHostTransitionStatus:Ri,useFormState:ui,useActionState:ui,useOptimistic:function(e){var t=Bo();t.memoizedState=t.baseState=e;var n={pending:null,lanes:0,dispatch:null,lastRenderedReducer:null,lastRenderedState:null};return t.queue=n,t=$i.bind(null,wo,!0,n),n.dispatch=t,[e,t]},useMemoCache:qo,useCacheRefresh:function(){return Bo().memoizedState=Fi.bind(null,wo)}},Wi={readContext:Ca,use:Uo,useCallback:Ei,useContext:Ca,useEffect:vi,useImperativeHandle:xi,useInsertionEffect:wi,useLayoutEffect:ki,useMemo:Ci,useReducer:Go,useRef:hi,useState:function(){return Go(Ho)},useDebugValue:_i,useDeferredValue:function(e,t){return Ti(zo(),ko.memoizedState,e,t)},useTransition:function(){var e=Go(Ho)[0],t=zo().memoizedState;return["boolean"==typeof e?e:$o(e),t]},useSyncExternalStore:Qo,useId:Mi,useHostTransitionStatus:Ri,useFormState:ci,useActionState:ci,useOptimistic:function(e,t){return ti(zo(),0,e,t)},useMemoCache:qo,useCacheRefresh:Di},Qi={readContext:Ca,use:Uo,useCallback:Ei,useContext:Ca,useEffect:vi,useImperativeHandle:xi,useInsertionEffect:wi,useLayoutEffect:ki,useMemo:Ci,useReducer:Wo,useRef:hi,useState:function(){return Wo(Ho)},useDebugValue:_i,useDeferredValue:function(e,t){var n=zo();return null===ko?Ai(n,e,t):Ti(n,ko.memoizedState,e,t)},useTransition:function(){var e=Wo(Ho)[0],t=zo().memoizedState;return["boolean"==typeof e?e:$o(e),t]},useSyncExternalStore:Qo,useId:Mi,useHostTransitionStatus:Ri,useFormState:pi,useActionState:pi,useOptimistic:function(e,t){var n=zo();return null!==ko?ti(n,0,e,t):(n.baseState=e,[e,n.queue.dispatch])},useMemoCache:qo,useCacheRefresh:Di},Ki=null,Yi=0;function Xi(e){var t=Yi;return Yi+=1,null===Ki&&(Ki=[]),Xa(Ki,e,t)}function Zi(e,t){t=t.props.ref,e.ref=void 0!==t?t:null}function Ji(e,t){if(t.$$typeof===p)throw Error(i(525));throw e=Object.prototype.toString.call(t),Error(i(31,"[object Object]"===e?"object with keys {"+Object.keys(t).join(", ")+"}":e))}function el(e){return(0,e._init)(e._payload)}function tl(e){function t(t,n){if(e){var r=t.deletions;null===r?(t.deletions=[n],t.flags|=16):r.push(n)}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e){for(var t=new Map;null!==e;)null!==e.key?t.set(e.key,e):t.set(e.index,e),e=e.sibling;return t}function a(e,t){return(e=Ir(e,t)).index=0,e.sibling=null,e}function o(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.flags|=67108866,n):r:(t.flags|=67108866,n):(t.flags|=1048576,n)}function l(t){return e&&null===t.alternate&&(t.flags|=67108866),t}function s(e,t,n,r){return null===t||6!==t.tag?((t=Ur(n,e.mode,r)).return=e,t):((t=a(t,n)).return=e,t)}function u(e,t,n,r){var o=n.type;return o===g?d(e,t,n.props.children,r,n.key):null!==t&&(t.elementType===o||"object"==typeof o&&null!==o&&o.$$typeof===C&&el(o)===t.type)?(Zi(t=a(t,n.props),n),t.return=e,t):(Zi(t=zr(n.type,n.key,n.props,null,e.mode,r),n),t.return=e,t)}function c(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=qr(n,e.mode,r)).return=e,t):((t=a(t,n.children||[])).return=e,t)}function d(e,t,n,r,o){return null===t||7!==t.tag?((t=$r(n,e.mode,r,o)).return=e,t):((t=a(t,n)).return=e,t)}function f(e,t,n){if("string"==typeof t&&""!==t||"number"==typeof t||"bigint"==typeof t)return(t=Ur(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case m:return Zi(n=zr(t.type,t.key,t.props,null,e.mode,n),t),n.return=e,n;case h:return(t=qr(t,e.mode,n)).return=e,t;case C:return f(e,t=(0,t._init)(t._payload),n)}if(O(t)||j(t))return(t=$r(t,e.mode,n,null)).return=e,t;if("function"==typeof t.then)return f(e,Xi(t),n);if(t.$$typeof===k)return f(e,Aa(e,t),n);Ji(e,t)}return null}function p(e,t,n,r){var a=null!==t?t.key:null;if("string"==typeof n&&""!==n||"number"==typeof n||"bigint"==typeof n)return null!==a?null:s(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case m:return n.key===a?u(e,t,n,r):null;case h:return n.key===a?c(e,t,n,r):null;case C:return p(e,t,n=(a=n._init)(n._payload),r)}if(O(n)||j(n))return null!==a?null:d(e,t,n,r,null);if("function"==typeof n.then)return p(e,t,Xi(n),r);if(n.$$typeof===k)return p(e,t,Aa(e,n),r);Ji(e,n)}return null}function y(e,t,n,r,a){if("string"==typeof r&&""!==r||"number"==typeof r||"bigint"==typeof r)return s(t,e=e.get(n)||null,""+r,a);if("object"==typeof r&&null!==r){switch(r.$$typeof){case m:return u(t,e=e.get(null===r.key?n:r.key)||null,r,a);case h:return c(t,e=e.get(null===r.key?n:r.key)||null,r,a);case C:return y(e,t,n,r=(0,r._init)(r._payload),a)}if(O(r)||j(r))return d(t,e=e.get(n)||null,r,a,null);if("function"==typeof r.then)return y(e,t,n,Xi(r),a);if(r.$$typeof===k)return y(e,t,n,Aa(t,r),a);Ji(t,r)}return null}function b(s,u,c,d){if("object"==typeof c&&null!==c&&c.type===g&&null===c.key&&(c=c.props.children),"object"==typeof c&&null!==c){switch(c.$$typeof){case m:e:{for(var v=c.key;null!==u;){if(u.key===v){if((v=c.type)===g){if(7===u.tag){n(s,u.sibling),(d=a(u,c.props.children)).return=s,s=d;break e}}else if(u.elementType===v||"object"==typeof v&&null!==v&&v.$$typeof===C&&el(v)===u.type){n(s,u.sibling),Zi(d=a(u,c.props),c),d.return=s,s=d;break e}n(s,u);break}t(s,u),u=u.sibling}c.type===g?((d=$r(c.props.children,s.mode,d,c.key)).return=s,s=d):(Zi(d=zr(c.type,c.key,c.props,null,s.mode,d),c),d.return=s,s=d)}return l(s);case h:e:{for(v=c.key;null!==u;){if(u.key===v){if(4===u.tag&&u.stateNode.containerInfo===c.containerInfo&&u.stateNode.implementation===c.implementation){n(s,u.sibling),(d=a(u,c.children||[])).return=s,s=d;break e}n(s,u);break}t(s,u),u=u.sibling}(d=qr(c,s.mode,d)).return=s,s=d}return l(s);case C:return b(s,u,c=(v=c._init)(c._payload),d)}if(O(c))return function(a,i,l,s){for(var u=null,c=null,d=i,m=i=0,h=null;null!==d&&m<l.length;m++){d.index>m?(h=d,d=null):h=d.sibling;var g=p(a,d,l[m],s);if(null===g){null===d&&(d=h);break}e&&d&&null===g.alternate&&t(a,d),i=o(g,i,m),null===c?u=g:c.sibling=g,c=g,d=h}if(m===l.length)return n(a,d),oa&&Jr(a,m),u;if(null===d){for(;m<l.length;m++)null!==(d=f(a,l[m],s))&&(i=o(d,i,m),null===c?u=d:c.sibling=d,c=d);return oa&&Jr(a,m),u}for(d=r(d);m<l.length;m++)null!==(h=y(d,a,m,l[m],s))&&(e&&null!==h.alternate&&d.delete(null===h.key?m:h.key),i=o(h,i,m),null===c?u=h:c.sibling=h,c=h);return e&&d.forEach((function(e){return t(a,e)})),oa&&Jr(a,m),u}(s,u,c,d);if(j(c)){if("function"!=typeof(v=j(c)))throw Error(i(150));return function(a,l,s,u){if(null==s)throw Error(i(151));for(var c=null,d=null,m=l,h=l=0,g=null,b=s.next();null!==m&&!b.done;h++,b=s.next()){m.index>h?(g=m,m=null):g=m.sibling;var v=p(a,m,b.value,u);if(null===v){null===m&&(m=g);break}e&&m&&null===v.alternate&&t(a,m),l=o(v,l,h),null===d?c=v:d.sibling=v,d=v,m=g}if(b.done)return n(a,m),oa&&Jr(a,h),c;if(null===m){for(;!b.done;h++,b=s.next())null!==(b=f(a,b.value,u))&&(l=o(b,l,h),null===d?c=b:d.sibling=b,d=b);return oa&&Jr(a,h),c}for(m=r(m);!b.done;h++,b=s.next())null!==(b=y(m,a,h,b.value,u))&&(e&&null!==b.alternate&&m.delete(null===b.key?h:b.key),l=o(b,l,h),null===d?c=b:d.sibling=b,d=b);return e&&m.forEach((function(e){return t(a,e)})),oa&&Jr(a,h),c}(s,u,c=v.call(c),d)}if("function"==typeof c.then)return b(s,u,Xi(c),d);if(c.$$typeof===k)return b(s,u,Aa(s,c),d);Ji(s,c)}return"string"==typeof c&&""!==c||"number"==typeof c||"bigint"==typeof c?(c=""+c,null!==u&&6===u.tag?(n(s,u.sibling),(d=a(u,c)).return=s,s=d):(n(s,u),(d=Ur(c,s.mode,d)).return=s,s=d),l(s)):n(s,u)}return function(e,t,n,r){try{Yi=0;var a=b(e,t,n,r);return Ki=null,a}catch(i){if(i===Ga||i===Wa)throw i;var o=Dr(29,i,null,e.mode);return o.lanes=r,o.return=e,o}}}var nl=tl(!0),rl=tl(!1),al=B(null),ol=null;function il(e){var t=e.alternate;$(cl,1&cl.current),$(al,e),null===ol&&(null===t||null!==mo.current||null!==t.memoizedState)&&(ol=e)}function ll(e){if(22===e.tag){if($(cl,cl.current),$(al,e),null===ol){var t=e.alternate;null!==t&&null!==t.memoizedState&&(ol=e)}}else sl()}function sl(){$(cl,cl.current),$(al,al.current)}function ul(e){z(al),ol===e&&(ol=null),z(cl)}var cl=B(0);function dl(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||gd(n)))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(128&t.flags)return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}function fl(e,t,n,r){n=null==(n=n(r,t=e.memoizedState))?t:f({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var pl={enqueueSetState:function(e,t,n){e=e._reactInternals;var r=Ru(),a=ao(r);a.payload=t,null!=n&&(a.callback=n),null!==(t=oo(e,a,r))&&(Du(t,e,r),io(t,e,r))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=Ru(),a=ao(r);a.tag=1,a.payload=t,null!=n&&(a.callback=n),null!==(t=oo(e,a,r))&&(Du(t,e,r),io(t,e,r))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=Ru(),r=ao(n);r.tag=2,null!=t&&(r.callback=t),null!==(t=oo(e,r,n))&&(Du(t,e,n),io(t,e,n))}};function ml(e,t,n,r,a,o,i){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,o,i):!t.prototype||!t.prototype.isPureReactComponent||(!Yn(n,r)||!Yn(a,o))}function hl(e,t,n,r){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&pl.enqueueReplaceState(t,t.state,null)}function gl(e,t){var n=t;if("ref"in t)for(var r in n={},t)"ref"!==r&&(n[r]=t[r]);if(e=e.defaultProps)for(var a in n===t&&(n=f({},n)),e)void 0===n[a]&&(n[a]=e[a]);return n}var yl="function"==typeof reportError?reportError:function(e){if("object"==typeof window&&"function"==typeof window.ErrorEvent){var t=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:"object"==typeof e&&null!==e&&"string"==typeof e.message?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if("object"==typeof process&&"function"==typeof process.emit)return void process.emit("uncaughtException",e);console.error(e)};function bl(e){yl(e)}function vl(e){console.error(e)}function wl(e){yl(e)}function kl(e,t){try{(0,e.onUncaughtError)(t.value,{componentStack:t.stack})}catch(n){setTimeout((function(){throw n}))}}function Sl(e,t,n){try{(0,e.onCaughtError)(n.value,{componentStack:n.stack,errorBoundary:1===t.tag?t.stateNode:null})}catch(r){setTimeout((function(){throw r}))}}function xl(e,t,n){return(n=ao(n)).tag=3,n.payload={element:null},n.callback=function(){kl(e,t)},n}function _l(e){return(e=ao(e)).tag=3,e}function El(e,t,n,r){var a=n.type.getDerivedStateFromError;if("function"==typeof a){var o=r.value;e.payload=function(){return a(o)},e.callback=function(){Sl(t,n,r)}}var i=n.stateNode;null!==i&&"function"==typeof i.componentDidCatch&&(e.callback=function(){Sl(t,n,r),"function"!=typeof a&&(null===_u?_u=new Set([this]):_u.add(this));var e=r.stack;this.componentDidCatch(r.value,{componentStack:null!==e?e:""})})}var Cl=Error(i(461)),Al=!1;function Tl(e,t,n,r){t.child=null===e?rl(t,null,n,r):nl(t,e.child,n,r)}function Ll(e,t,n,r,a){n=n.render;var o=t.ref;if("ref"in r){var i={};for(var l in r)"ref"!==l&&(i[l]=r[l])}else i=r;return Ea(t),r=No(e,t,n,i,o,a),l=Do(),null===e||Al?(oa&&l&&ta(t),t.flags|=1,Tl(e,t,r,a),t.child):(Fo(e,t,a),Kl(e,t,a))}function jl(e,t,n,r,a){if(null===e){var o=n.type;return"function"!=typeof o||Fr(o)||void 0!==o.defaultProps||null!==n.compare?((e=zr(n.type,null,r,t,t.mode,a)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=o,Pl(e,t,o,r,a))}if(o=e.child,!Yl(e,a)){var i=o.memoizedProps;if((n=null!==(n=n.compare)?n:Yn)(i,r)&&e.ref===t.ref)return Kl(e,t,a)}return t.flags|=1,(e=Ir(o,r)).ref=t.ref,e.return=t,t.child=e}function Pl(e,t,n,r,a){if(null!==e){var o=e.memoizedProps;if(Yn(o,r)&&e.ref===t.ref){if(Al=!1,t.pendingProps=r=o,!Yl(e,a))return t.lanes=e.lanes,Kl(e,t,a);131072&e.flags&&(Al=!0)}}return Ml(e,t,n,r,a)}function Nl(e,t,n){var r=t.pendingProps,a=r.children,o=null!==e?e.memoizedState:null;if("hidden"===r.mode){if(128&t.flags){if(r=null!==o?o.baseLanes|n:n,null!==e){for(a=t.child=e.child,o=0;null!==a;)o=o|a.lanes|a.childLanes,a=a.sibling;t.childLanes=o&~r}else t.childLanes=0,t.child=null;return Ol(e,t,r,n)}if(!(536870912&n))return t.lanes=t.childLanes=536870912,Ol(e,t,null!==o?o.baseLanes|n:n,n);t.memoizedState={baseLanes:0,cachePool:null},null!==e&&qa(0,null!==o?o.cachePool:null),null!==o?go(t,o):yo(),ll(t)}else null!==o?(qa(0,o.cachePool),go(t,o),sl(),t.memoizedState=null):(null!==e&&qa(0,null),yo(),sl());return Tl(e,t,a,n),t.child}function Ol(e,t,n,r){var a=Ua();return a=null===a?null:{parent:Na._currentValue,pool:a},t.memoizedState={baseLanes:n,cachePool:a},null!==e&&qa(0,null),yo(),ll(t),null!==e&&xa(e,t,r,!0),null}function Rl(e,t){var n=t.ref;if(null===n)null!==e&&null!==e.ref&&(t.flags|=4194816);else{if("function"!=typeof n&&"object"!=typeof n)throw Error(i(284));null!==e&&e.ref===n||(t.flags|=4194816)}}function Ml(e,t,n,r,a){return Ea(t),n=No(e,t,n,r,void 0,a),r=Do(),null===e||Al?(oa&&r&&ta(t),t.flags|=1,Tl(e,t,n,a),t.child):(Fo(e,t,a),Kl(e,t,a))}function Dl(e,t,n,r,a,o){return Ea(t),t.updateQueue=null,n=Ro(t,r,n,a),Oo(e),r=Do(),null===e||Al?(oa&&r&&ta(t),t.flags|=1,Tl(e,t,n,o),t.child):(Fo(e,t,o),Kl(e,t,o))}function Fl(e,t,n,r,a){if(Ea(t),null===t.stateNode){var o=Rr,i=n.contextType;"object"==typeof i&&null!==i&&(o=Ca(i)),o=new n(r,o),t.memoizedState=null!==o.state&&void 0!==o.state?o.state:null,o.updater=pl,t.stateNode=o,o._reactInternals=t,(o=t.stateNode).props=r,o.state=t.memoizedState,o.refs={},no(t),i=n.contextType,o.context="object"==typeof i&&null!==i?Ca(i):Rr,o.state=t.memoizedState,"function"==typeof(i=n.getDerivedStateFromProps)&&(fl(t,n,i,r),o.state=t.memoizedState),"function"==typeof n.getDerivedStateFromProps||"function"==typeof o.getSnapshotBeforeUpdate||"function"!=typeof o.UNSAFE_componentWillMount&&"function"!=typeof o.componentWillMount||(i=o.state,"function"==typeof o.componentWillMount&&o.componentWillMount(),"function"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount(),i!==o.state&&pl.enqueueReplaceState(o,o.state,null),co(t,r,o,a),uo(),o.state=t.memoizedState),"function"==typeof o.componentDidMount&&(t.flags|=4194308),r=!0}else if(null===e){o=t.stateNode;var l=t.memoizedProps,s=gl(n,l);o.props=s;var u=o.context,c=n.contextType;i=Rr,"object"==typeof c&&null!==c&&(i=Ca(c));var d=n.getDerivedStateFromProps;c="function"==typeof d||"function"==typeof o.getSnapshotBeforeUpdate,l=t.pendingProps!==l,c||"function"!=typeof o.UNSAFE_componentWillReceiveProps&&"function"!=typeof o.componentWillReceiveProps||(l||u!==i)&&hl(t,o,r,i),to=!1;var f=t.memoizedState;o.state=f,co(t,r,o,a),uo(),u=t.memoizedState,l||f!==u||to?("function"==typeof d&&(fl(t,n,d,r),u=t.memoizedState),(s=to||ml(t,n,s,r,f,u,i))?(c||"function"!=typeof o.UNSAFE_componentWillMount&&"function"!=typeof o.componentWillMount||("function"==typeof o.componentWillMount&&o.componentWillMount(),"function"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount()),"function"==typeof o.componentDidMount&&(t.flags|=4194308)):("function"==typeof o.componentDidMount&&(t.flags|=4194308),t.memoizedProps=r,t.memoizedState=u),o.props=r,o.state=u,o.context=i,r=s):("function"==typeof o.componentDidMount&&(t.flags|=4194308),r=!1)}else{o=t.stateNode,ro(e,t),c=gl(n,i=t.memoizedProps),o.props=c,d=t.pendingProps,f=o.context,u=n.contextType,s=Rr,"object"==typeof u&&null!==u&&(s=Ca(u)),(u="function"==typeof(l=n.getDerivedStateFromProps)||"function"==typeof o.getSnapshotBeforeUpdate)||"function"!=typeof o.UNSAFE_componentWillReceiveProps&&"function"!=typeof o.componentWillReceiveProps||(i!==d||f!==s)&&hl(t,o,r,s),to=!1,f=t.memoizedState,o.state=f,co(t,r,o,a),uo();var p=t.memoizedState;i!==d||f!==p||to||null!==e&&null!==e.dependencies&&_a(e.dependencies)?("function"==typeof l&&(fl(t,n,l,r),p=t.memoizedState),(c=to||ml(t,n,c,r,f,p,s)||null!==e&&null!==e.dependencies&&_a(e.dependencies))?(u||"function"!=typeof o.UNSAFE_componentWillUpdate&&"function"!=typeof o.componentWillUpdate||("function"==typeof o.componentWillUpdate&&o.componentWillUpdate(r,p,s),"function"==typeof o.UNSAFE_componentWillUpdate&&o.UNSAFE_componentWillUpdate(r,p,s)),"function"==typeof o.componentDidUpdate&&(t.flags|=4),"function"==typeof o.getSnapshotBeforeUpdate&&(t.flags|=1024)):("function"!=typeof o.componentDidUpdate||i===e.memoizedProps&&f===e.memoizedState||(t.flags|=4),"function"!=typeof o.getSnapshotBeforeUpdate||i===e.memoizedProps&&f===e.memoizedState||(t.flags|=1024),t.memoizedProps=r,t.memoizedState=p),o.props=r,o.state=p,o.context=s,r=c):("function"!=typeof o.componentDidUpdate||i===e.memoizedProps&&f===e.memoizedState||(t.flags|=4),"function"!=typeof o.getSnapshotBeforeUpdate||i===e.memoizedProps&&f===e.memoizedState||(t.flags|=1024),r=!1)}return o=r,Rl(e,t),r=!!(128&t.flags),o||r?(o=t.stateNode,n=r&&"function"!=typeof n.getDerivedStateFromError?null:o.render(),t.flags|=1,null!==e&&r?(t.child=nl(t,e.child,null,a),t.child=nl(t,null,n,a)):Tl(e,t,n,a),t.memoizedState=o.state,e=t.child):e=Kl(e,t,a),e}function Il(e,t,n,r){return pa(),t.flags|=256,Tl(e,t,n,r),t.child}var Bl={dehydrated:null,treeContext:null,retryLane:0,hydrationErrors:null};function zl(e){return{baseLanes:e,cachePool:Ha()}}function $l(e,t,n){return e=null!==e?e.childLanes&~n:0,t&&(e|=gu),e}function Ul(e,t,n){var r,a=t.pendingProps,o=!1,l=!!(128&t.flags);if((r=l)||(r=(null===e||null!==e.memoizedState)&&!!(2&cl.current)),r&&(o=!0,t.flags&=-129),r=!!(32&t.flags),t.flags&=-33,null===e){if(oa){if(o?il(t):sl(),oa){var s,u=aa;if(s=u){e:{for(s=u,u=la;8!==s.nodeType;){if(!u){u=null;break e}if(null===(s=yd(s.nextSibling))){u=null;break e}}u=s}null!==u?(t.memoizedState={dehydrated:u,treeContext:null!==Yr?{id:Xr,overflow:Zr}:null,retryLane:536870912,hydrationErrors:null},(s=Dr(18,null,null,0)).stateNode=u,s.return=t,t.child=s,ra=t,aa=null,s=!0):s=!1}s||ua(t)}if(null!==(u=t.memoizedState)&&null!==(u=u.dehydrated))return gd(u)?t.lanes=32:t.lanes=536870912,null;ul(t)}return u=a.children,a=a.fallback,o?(sl(),u=Hl({mode:"hidden",children:u},o=t.mode),a=$r(a,o,n,null),u.return=t,a.return=t,u.sibling=a,t.child=u,(o=t.child).memoizedState=zl(n),o.childLanes=$l(e,r,n),t.memoizedState=Bl,a):(il(t),ql(t,u))}if(null!==(s=e.memoizedState)&&null!==(u=s.dehydrated)){if(l)256&t.flags?(il(t),t.flags&=-257,t=Gl(e,t,n)):null!==t.memoizedState?(sl(),t.child=e.child,t.flags|=128,t=null):(sl(),o=a.fallback,u=t.mode,a=Hl({mode:"visible",children:a.children},u),(o=$r(o,u,n,null)).flags|=2,a.return=t,o.return=t,a.sibling=o,t.child=a,nl(t,e.child,null,n),(a=t.child).memoizedState=zl(n),a.childLanes=$l(e,r,n),t.memoizedState=Bl,t=o);else if(il(t),gd(u)){if(r=u.nextSibling&&u.nextSibling.dataset)var c=r.dgst;r=c,(a=Error(i(419))).stack="",a.digest=r,ha({value:a,source:null,stack:null}),t=Gl(e,t,n)}else if(Al||xa(e,t,n,!1),r=0!==(n&e.childLanes),Al||r){if(null!==(r=ru)&&(0!==(a=0!==((a=42&(a=n&-n)?1:Te(a))&(r.suspendedLanes|n))?0:a)&&a!==s.retryLane))throw s.retryLane=a,Pr(e,a),Du(r,e,a),Cl;"$?"===u.data||Wu(),t=Gl(e,t,n)}else"$?"===u.data?(t.flags|=192,t.child=e.child,t=null):(e=s.treeContext,aa=yd(u.nextSibling),ra=t,oa=!0,ia=null,la=!1,null!==e&&(Qr[Kr++]=Xr,Qr[Kr++]=Zr,Qr[Kr++]=Yr,Xr=e.id,Zr=e.overflow,Yr=t),(t=ql(t,a.children)).flags|=4096);return t}return o?(sl(),o=a.fallback,u=t.mode,c=(s=e.child).sibling,(a=Ir(s,{mode:"hidden",children:a.children})).subtreeFlags=65011712&s.subtreeFlags,null!==c?o=Ir(c,o):(o=$r(o,u,n,null)).flags|=2,o.return=t,a.return=t,a.sibling=o,t.child=a,a=o,o=t.child,null===(u=e.child.memoizedState)?u=zl(n):(null!==(s=u.cachePool)?(c=Na._currentValue,s=s.parent!==c?{parent:c,pool:c}:s):s=Ha(),u={baseLanes:u.baseLanes|n,cachePool:s}),o.memoizedState=u,o.childLanes=$l(e,r,n),t.memoizedState=Bl,a):(il(t),e=(n=e.child).sibling,(n=Ir(n,{mode:"visible",children:a.children})).return=t,n.sibling=null,null!==e&&(null===(r=t.deletions)?(t.deletions=[e],t.flags|=16):r.push(e)),t.child=n,t.memoizedState=null,n)}function ql(e,t){return(t=Hl({mode:"visible",children:t},e.mode)).return=e,e.child=t}function Hl(e,t){return(e=Dr(22,e,null,t)).lanes=0,e.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null},e}function Gl(e,t,n){return nl(t,e.child,null,n),(e=ql(t,t.pendingProps.children)).flags|=2,t.memoizedState=null,e}function Vl(e,t,n){e.lanes|=t;var r=e.alternate;null!==r&&(r.lanes|=t),ka(e.return,t,n)}function Wl(e,t,n,r,a){var o=e.memoizedState;null===o?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:a}:(o.isBackwards=t,o.rendering=null,o.renderingStartTime=0,o.last=r,o.tail=n,o.tailMode=a)}function Ql(e,t,n){var r=t.pendingProps,a=r.revealOrder,o=r.tail;if(Tl(e,t,r.children,n),2&(r=cl.current))r=1&r|2,t.flags|=128;else{if(null!==e&&128&e.flags)e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&Vl(e,n,t);else if(19===e.tag)Vl(e,n,t);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}switch($(cl,r),a){case"forwards":for(n=t.child,a=null;null!==n;)null!==(e=n.alternate)&&null===dl(e)&&(a=n),n=n.sibling;null===(n=a)?(a=t.child,t.child=null):(a=n.sibling,n.sibling=null),Wl(t,!1,a,n,o);break;case"backwards":for(n=null,a=t.child,t.child=null;null!==a;){if(null!==(e=a.alternate)&&null===dl(e)){t.child=a;break}e=a.sibling,a.sibling=n,n=a,a=e}Wl(t,!0,n,null,o);break;case"together":Wl(t,!1,null,null,void 0);break;default:t.memoizedState=null}return t.child}function Kl(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),pu|=t.lanes,0===(n&t.childLanes)){if(null===e)return null;if(xa(e,t,n,!1),0===(n&t.childLanes))return null}if(null!==e&&t.child!==e.child)throw Error(i(153));if(null!==t.child){for(n=Ir(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Ir(e,e.pendingProps)).return=t;n.sibling=null}return t.child}function Yl(e,t){return 0!==(e.lanes&t)||!(null===(e=e.dependencies)||!_a(e))}function Xl(e,t,n){if(null!==e)if(e.memoizedProps!==t.pendingProps)Al=!0;else{if(!(Yl(e,n)||128&t.flags))return Al=!1,function(e,t,n){switch(t.tag){case 3:V(t,t.stateNode.containerInfo),va(0,Na,e.memoizedState.cache),pa();break;case 27:case 5:Q(t);break;case 4:V(t,t.stateNode.containerInfo);break;case 10:va(0,t.type,t.memoizedProps.value);break;case 13:var r=t.memoizedState;if(null!==r)return null!==r.dehydrated?(il(t),t.flags|=128,null):0!==(n&t.child.childLanes)?Ul(e,t,n):(il(t),null!==(e=Kl(e,t,n))?e.sibling:null);il(t);break;case 19:var a=!!(128&e.flags);if((r=0!==(n&t.childLanes))||(xa(e,t,n,!1),r=0!==(n&t.childLanes)),a){if(r)return Ql(e,t,n);t.flags|=128}if(null!==(a=t.memoizedState)&&(a.rendering=null,a.tail=null,a.lastEffect=null),$(cl,cl.current),r)break;return null;case 22:case 23:return t.lanes=0,Nl(e,t,n);case 24:va(0,Na,e.memoizedState.cache)}return Kl(e,t,n)}(e,t,n);Al=!!(131072&e.flags)}else Al=!1,oa&&1048576&t.flags&&ea(t,Wr,t.index);switch(t.lanes=0,t.tag){case 16:e:{e=t.pendingProps;var r=t.elementType,a=r._init;if(r=a(r._payload),t.type=r,"function"!=typeof r){if(null!=r){if((a=r.$$typeof)===S){t.tag=11,t=Ll(null,t,r,e,n);break e}if(a===E){t.tag=14,t=jl(null,t,r,e,n);break e}}throw t=N(r)||r,Error(i(306,t,""))}Fr(r)?(e=gl(r,e),t.tag=1,t=Fl(null,t,r,e,n)):(t.tag=0,t=Ml(null,t,r,e,n))}return t;case 0:return Ml(e,t,t.type,t.pendingProps,n);case 1:return Fl(e,t,r=t.type,a=gl(r,t.pendingProps),n);case 3:e:{if(V(t,t.stateNode.containerInfo),null===e)throw Error(i(387));r=t.pendingProps;var o=t.memoizedState;a=o.element,ro(e,t),co(t,r,null,n);var l=t.memoizedState;if(r=l.cache,va(0,Na,r),r!==o.cache&&Sa(t,[Na],n,!0),uo(),r=l.element,o.isDehydrated){if(o={element:r,isDehydrated:!1,cache:l.cache},t.updateQueue.baseState=o,t.memoizedState=o,256&t.flags){t=Il(e,t,r,n);break e}if(r!==a){ha(a=_r(Error(i(424)),t)),t=Il(e,t,r,n);break e}if(9===(e=t.stateNode.containerInfo).nodeType)e=e.body;else e="HTML"===e.nodeName?e.ownerDocument.body:e;for(aa=yd(e.firstChild),ra=t,oa=!0,ia=null,la=!0,n=rl(t,null,r,n),t.child=n;n;)n.flags=-3&n.flags|4096,n=n.sibling}else{if(pa(),r===a){t=Kl(e,t,n);break e}Tl(e,t,r,n)}t=t.child}return t;case 26:return Rl(e,t),null===e?(n=Td(t.type,null,t.pendingProps,null))?t.memoizedState=n:oa||(n=t.type,e=t.pendingProps,(r=rd(H.current).createElement(n))[Ne]=t,r[Oe]=e,ed(r,n,e),Ge(r),t.stateNode=r):t.memoizedState=Td(t.type,e.memoizedProps,t.pendingProps,e.memoizedState),null;case 27:return Q(t),null===e&&oa&&(r=t.stateNode=wd(t.type,t.pendingProps,H.current),ra=t,la=!0,a=aa,pd(t.type)?(bd=a,aa=yd(r.firstChild)):aa=a),Tl(e,t,t.pendingProps.children,n),Rl(e,t),null===e&&(t.flags|=4194304),t.child;case 5:return null===e&&oa&&((a=r=aa)&&(null!==(r=function(e,t,n,r){for(;1===e.nodeType;){var a=n;if(e.nodeName.toLowerCase()!==t.toLowerCase()){if(!r&&("INPUT"!==e.nodeName||"hidden"!==e.type))break}else if(r){if(!e[Be])switch(t){case"meta":if(!e.hasAttribute("itemprop"))break;return e;case"link":if("stylesheet"===(o=e.getAttribute("rel"))&&e.hasAttribute("data-precedence"))break;if(o!==a.rel||e.getAttribute("href")!==(null==a.href||""===a.href?null:a.href)||e.getAttribute("crossorigin")!==(null==a.crossOrigin?null:a.crossOrigin)||e.getAttribute("title")!==(null==a.title?null:a.title))break;return e;case"style":if(e.hasAttribute("data-precedence"))break;return e;case"script":if(((o=e.getAttribute("src"))!==(null==a.src?null:a.src)||e.getAttribute("type")!==(null==a.type?null:a.type)||e.getAttribute("crossorigin")!==(null==a.crossOrigin?null:a.crossOrigin))&&o&&e.hasAttribute("async")&&!e.hasAttribute("itemprop"))break;return e;default:return e}}else{if("input"!==t||"hidden"!==e.type)return e;var o=null==a.name?null:""+a.name;if("hidden"===a.type&&e.getAttribute("name")===o)return e}if(null===(e=yd(e.nextSibling)))break}return null}(r,t.type,t.pendingProps,la))?(t.stateNode=r,ra=t,aa=yd(r.firstChild),la=!1,a=!0):a=!1),a||ua(t)),Q(t),a=t.type,o=t.pendingProps,l=null!==e?e.memoizedProps:null,r=o.children,id(a,o)?r=null:null!==l&&id(a,l)&&(t.flags|=32),null!==t.memoizedState&&(a=No(e,t,Mo,null,null,n),Qd._currentValue=a),Rl(e,t),Tl(e,t,r,n),t.child;case 6:return null===e&&oa&&((e=n=aa)&&(null!==(n=function(e,t,n){if(""===t)return null;for(;3!==e.nodeType;){if((1!==e.nodeType||"INPUT"!==e.nodeName||"hidden"!==e.type)&&!n)return null;if(null===(e=yd(e.nextSibling)))return null}return e}(n,t.pendingProps,la))?(t.stateNode=n,ra=t,aa=null,e=!0):e=!1),e||ua(t)),null;case 13:return Ul(e,t,n);case 4:return V(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=nl(t,null,r,n):Tl(e,t,r,n),t.child;case 11:return Ll(e,t,t.type,t.pendingProps,n);case 7:return Tl(e,t,t.pendingProps,n),t.child;case 8:case 12:return Tl(e,t,t.pendingProps.children,n),t.child;case 10:return r=t.pendingProps,va(0,t.type,r.value),Tl(e,t,r.children,n),t.child;case 9:return a=t.type._context,r=t.pendingProps.children,Ea(t),r=r(a=Ca(a)),t.flags|=1,Tl(e,t,r,n),t.child;case 14:return jl(e,t,t.type,t.pendingProps,n);case 15:return Pl(e,t,t.type,t.pendingProps,n);case 19:return Ql(e,t,n);case 31:return r=t.pendingProps,n=t.mode,r={mode:r.mode,children:r.children},null===e?((n=Hl(r,n)).ref=t.ref,t.child=n,n.return=t,t=n):((n=Ir(e.child,r)).ref=t.ref,t.child=n,n.return=t,t=n),t;case 22:return Nl(e,t,n);case 24:return Ea(t),r=Ca(Na),null===e?(null===(a=Ua())&&(a=ru,o=Oa(),a.pooledCache=o,o.refCount++,null!==o&&(a.pooledCacheLanes|=n),a=o),t.memoizedState={parent:r,cache:a},no(t),va(0,Na,a)):(0!==(e.lanes&n)&&(ro(e,t),co(t,null,null,n),uo()),a=e.memoizedState,o=t.memoizedState,a.parent!==r?(a={parent:r,cache:r},t.memoizedState=a,0===t.lanes&&(t.memoizedState=t.updateQueue.baseState=a),va(0,Na,r)):(r=o.cache,va(0,Na,r),r!==a.cache&&Sa(t,[Na],n,!0))),Tl(e,t,t.pendingProps.children,n),t.child;case 29:throw t.pendingProps}throw Error(i(156,t.tag))}function Zl(e){e.flags|=4}function Jl(e,t){if("stylesheet"!==t.type||4&t.state.loading)e.flags&=-16777217;else if(e.flags|=16777216,!$d(t)){if(null!==(t=al.current)&&((4194048&ou)===ou?null!==ol:(62914560&ou)!==ou&&!(536870912&ou)||t!==ol))throw Za=Qa,Va;e.flags|=8192}}function es(e,t){null!==t&&(e.flags|=4),16384&e.flags&&(t=22!==e.tag?xe():536870912,e.lanes|=t,yu|=t)}function ts(e,t){if(!oa)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?t||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function ns(e){var t=null!==e.alternate&&e.alternate.child===e.child,n=0,r=0;if(t)for(var a=e.child;null!==a;)n|=a.lanes|a.childLanes,r|=65011712&a.subtreeFlags,r|=65011712&a.flags,a.return=e,a=a.sibling;else for(a=e.child;null!==a;)n|=a.lanes|a.childLanes,r|=a.subtreeFlags,r|=a.flags,a.return=e,a=a.sibling;return e.subtreeFlags|=r,e.childLanes=n,t}function rs(e,t,n){var r=t.pendingProps;switch(na(t),t.tag){case 31:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:case 1:return ns(t),null;case 3:return n=t.stateNode,r=null,null!==e&&(r=e.memoizedState.cache),t.memoizedState.cache!==r&&(t.flags|=2048),wa(Na),W(),n.pendingContext&&(n.context=n.pendingContext,n.pendingContext=null),null!==e&&null!==e.child||(fa(t)?Zl(t):null===e||e.memoizedState.isDehydrated&&!(256&t.flags)||(t.flags|=1024,ma())),ns(t),null;case 26:return n=t.memoizedState,null===e?(Zl(t),null!==n?(ns(t),Jl(t,n)):(ns(t),t.flags&=-16777217)):n?n!==e.memoizedState?(Zl(t),ns(t),Jl(t,n)):(ns(t),t.flags&=-16777217):(e.memoizedProps!==r&&Zl(t),ns(t),t.flags&=-16777217),null;case 27:K(t),n=H.current;var a=t.type;if(null!==e&&null!=t.stateNode)e.memoizedProps!==r&&Zl(t);else{if(!r){if(null===t.stateNode)throw Error(i(166));return ns(t),null}e=U.current,fa(t)?ca(t):(e=wd(a,r,n),t.stateNode=e,Zl(t))}return ns(t),null;case 5:if(K(t),n=t.type,null!==e&&null!=t.stateNode)e.memoizedProps!==r&&Zl(t);else{if(!r){if(null===t.stateNode)throw Error(i(166));return ns(t),null}if(e=U.current,fa(t))ca(t);else{switch(a=rd(H.current),e){case 1:e=a.createElementNS("http://www.w3.org/2000/svg",n);break;case 2:e=a.createElementNS("http://www.w3.org/1998/Math/MathML",n);break;default:switch(n){case"svg":e=a.createElementNS("http://www.w3.org/2000/svg",n);break;case"math":e=a.createElementNS("http://www.w3.org/1998/Math/MathML",n);break;case"script":(e=a.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild);break;case"select":e="string"==typeof r.is?a.createElement("select",{is:r.is}):a.createElement("select"),r.multiple?e.multiple=!0:r.size&&(e.size=r.size);break;default:e="string"==typeof r.is?a.createElement(n,{is:r.is}):a.createElement(n)}}e[Ne]=t,e[Oe]=r;e:for(a=t.child;null!==a;){if(5===a.tag||6===a.tag)e.appendChild(a.stateNode);else if(4!==a.tag&&27!==a.tag&&null!==a.child){a.child.return=a,a=a.child;continue}if(a===t)break e;for(;null===a.sibling;){if(null===a.return||a.return===t)break e;a=a.return}a.sibling.return=a.return,a=a.sibling}t.stateNode=e;e:switch(ed(e,n,r),n){case"button":case"input":case"select":case"textarea":e=!!r.autoFocus;break e;case"img":e=!0;break e;default:e=!1}e&&Zl(t)}}return ns(t),t.flags&=-16777217,null;case 6:if(e&&null!=t.stateNode)e.memoizedProps!==r&&Zl(t);else{if("string"!=typeof r&&null===t.stateNode)throw Error(i(166));if(e=H.current,fa(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,null!==(a=ra))switch(a.tag){case 27:case 5:r=a.memoizedProps}e[Ne]=t,(e=!!(e.nodeValue===n||null!==r&&!0===r.suppressHydrationWarning||Yc(e.nodeValue,n)))||ua(t)}else(e=rd(e).createTextNode(r))[Ne]=t,t.stateNode=e}return ns(t),null;case 13:if(r=t.memoizedState,null===e||null!==e.memoizedState&&null!==e.memoizedState.dehydrated){if(a=fa(t),null!==r&&null!==r.dehydrated){if(null===e){if(!a)throw Error(i(318));if(!(a=null!==(a=t.memoizedState)?a.dehydrated:null))throw Error(i(317));a[Ne]=t}else pa(),!(128&t.flags)&&(t.memoizedState=null),t.flags|=4;ns(t),a=!1}else a=ma(),null!==e&&null!==e.memoizedState&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return 256&t.flags?(ul(t),t):(ul(t),null)}if(ul(t),128&t.flags)return t.lanes=n,t;if(n=null!==r,e=null!==e&&null!==e.memoizedState,n){a=null,null!==(r=t.child).alternate&&null!==r.alternate.memoizedState&&null!==r.alternate.memoizedState.cachePool&&(a=r.alternate.memoizedState.cachePool.pool);var o=null;null!==r.memoizedState&&null!==r.memoizedState.cachePool&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)}return n!==e&&n&&(t.child.flags|=8192),es(t,t.updateQueue),ns(t),null;case 4:return W(),null===e&&zc(t.stateNode.containerInfo),ns(t),null;case 10:return wa(t.type),ns(t),null;case 19:if(z(cl),null===(a=t.memoizedState))return ns(t),null;if(r=!!(128&t.flags),null===(o=a.rendering))if(r)ts(a,!1);else{if(0!==fu||null!==e&&128&e.flags)for(e=t.child;null!==e;){if(null!==(o=dl(e))){for(t.flags|=128,ts(a,!1),e=o.updateQueue,t.updateQueue=e,es(t,e),t.subtreeFlags=0,e=n,n=t.child;null!==n;)Br(n,e),n=n.sibling;return $(cl,1&cl.current|2),t.child}e=e.sibling}null!==a.tail&&te()>Su&&(t.flags|=128,r=!0,ts(a,!1),t.lanes=4194304)}else{if(!r)if(null!==(e=dl(o))){if(t.flags|=128,r=!0,e=e.updateQueue,t.updateQueue=e,es(t,e),ts(a,!0),null===a.tail&&"hidden"===a.tailMode&&!o.alternate&&!oa)return ns(t),null}else 2*te()-a.renderingStartTime>Su&&536870912!==n&&(t.flags|=128,r=!0,ts(a,!1),t.lanes=4194304);a.isBackwards?(o.sibling=t.child,t.child=o):(null!==(e=a.last)?e.sibling=o:t.child=o,a.last=o)}return null!==a.tail?(t=a.tail,a.rendering=t,a.tail=t.sibling,a.renderingStartTime=te(),t.sibling=null,e=cl.current,$(cl,r?1&e|2:1&e),t):(ns(t),null);case 22:case 23:return ul(t),bo(),r=null!==t.memoizedState,null!==e?null!==e.memoizedState!==r&&(t.flags|=8192):r&&(t.flags|=8192),r?!!(536870912&n)&&!(128&t.flags)&&(ns(t),6&t.subtreeFlags&&(t.flags|=8192)):ns(t),null!==(n=t.updateQueue)&&es(t,n.retryQueue),n=null,null!==e&&null!==e.memoizedState&&null!==e.memoizedState.cachePool&&(n=e.memoizedState.cachePool.pool),r=null,null!==t.memoizedState&&null!==t.memoizedState.cachePool&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),null!==e&&z($a),null;case 24:return n=null,null!==e&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),wa(Na),ns(t),null;case 25:case 30:return null}throw Error(i(156,t.tag))}function as(e,t){switch(na(t),t.tag){case 1:return 65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 3:return wa(Na),W(),65536&(e=t.flags)&&!(128&e)?(t.flags=-65537&e|128,t):null;case 26:case 27:case 5:return K(t),null;case 13:if(ul(t),null!==(e=t.memoizedState)&&null!==e.dehydrated){if(null===t.alternate)throw Error(i(340));pa()}return 65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 19:return z(cl),null;case 4:return W(),null;case 10:return wa(t.type),null;case 22:case 23:return ul(t),bo(),null!==e&&z($a),65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 24:return wa(Na),null;default:return null}}function os(e,t){switch(na(t),t.tag){case 3:wa(Na),W();break;case 26:case 27:case 5:K(t);break;case 4:W();break;case 13:ul(t);break;case 19:z(cl);break;case 10:wa(t.type);break;case 22:case 23:ul(t),bo(),null!==e&&z($a);break;case 24:wa(Na)}}function is(e,t){try{var n=t.updateQueue,r=null!==n?n.lastEffect:null;if(null!==r){var a=r.next;n=a;do{if((n.tag&e)===e){r=void 0;var o=n.create,i=n.inst;r=o(),i.destroy=r}n=n.next}while(n!==a)}}catch(l){cc(t,t.return,l)}}function ls(e,t,n){try{var r=t.updateQueue,a=null!==r?r.lastEffect:null;if(null!==a){var o=a.next;r=o;do{if((r.tag&e)===e){var i=r.inst,l=i.destroy;if(void 0!==l){i.destroy=void 0,a=t;var s=n,u=l;try{u()}catch(c){cc(a,s,c)}}}r=r.next}while(r!==o)}}catch(c){cc(t,t.return,c)}}function ss(e){var t=e.updateQueue;if(null!==t){var n=e.stateNode;try{po(t,n)}catch(r){cc(e,e.return,r)}}}function us(e,t,n){n.props=gl(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(r){cc(e,t,r)}}function cs(e,t){try{var n=e.ref;if(null!==n){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;default:r=e.stateNode}"function"==typeof n?e.refCleanup=n(r):n.current=r}}catch(a){cc(e,t,a)}}function ds(e,t){var n=e.ref,r=e.refCleanup;if(null!==n)if("function"==typeof r)try{r()}catch(a){cc(e,t,a)}finally{e.refCleanup=null,null!=(e=e.alternate)&&(e.refCleanup=null)}else if("function"==typeof n)try{n(null)}catch(o){cc(e,t,o)}else n.current=null}function fs(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{e:switch(t){case"button":case"input":case"select":case"textarea":n.autoFocus&&r.focus();break e;case"img":n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(a){cc(e,e.return,a)}}function ps(e,t,n){try{var r=e.stateNode;!function(e,t,n,r){switch(t){case"div":case"span":case"svg":case"path":case"a":case"g":case"p":case"li":break;case"input":var a=null,o=null,l=null,s=null,u=null,c=null,d=null;for(m in n){var f=n[m];if(n.hasOwnProperty(m)&&null!=f)switch(m){case"checked":case"value":break;case"defaultValue":u=f;default:r.hasOwnProperty(m)||Zc(e,t,m,null,r,f)}}for(var p in r){var m=r[p];if(f=n[p],r.hasOwnProperty(p)&&(null!=m||null!=f))switch(p){case"type":o=m;break;case"name":a=m;break;case"checked":c=m;break;case"defaultChecked":d=m;break;case"value":l=m;break;case"defaultValue":s=m;break;case"children":case"dangerouslySetInnerHTML":if(null!=m)throw Error(i(137,t));break;default:m!==f&&Zc(e,t,p,m,r,f)}}return void gt(e,l,s,u,c,d,o,a);case"select":for(o in m=l=s=p=null,n)if(u=n[o],n.hasOwnProperty(o)&&null!=u)switch(o){case"value":break;case"multiple":m=u;default:r.hasOwnProperty(o)||Zc(e,t,o,null,r,u)}for(a in r)if(o=r[a],u=n[a],r.hasOwnProperty(a)&&(null!=o||null!=u))switch(a){case"value":p=o;break;case"defaultValue":s=o;break;case"multiple":l=o;default:o!==u&&Zc(e,t,a,o,r,u)}return t=s,n=l,r=m,void(null!=p?vt(e,!!n,p,!1):!!r!=!!n&&(null!=t?vt(e,!!n,t,!0):vt(e,!!n,n?[]:"",!1)));case"textarea":for(s in m=p=null,n)if(a=n[s],n.hasOwnProperty(s)&&null!=a&&!r.hasOwnProperty(s))switch(s){case"value":case"children":break;default:Zc(e,t,s,null,r,a)}for(l in r)if(a=r[l],o=n[l],r.hasOwnProperty(l)&&(null!=a||null!=o))switch(l){case"value":p=a;break;case"defaultValue":m=a;break;case"children":break;case"dangerouslySetInnerHTML":if(null!=a)throw Error(i(91));break;default:a!==o&&Zc(e,t,l,a,r,o)}return void wt(e,p,m);case"option":for(var h in n)if(p=n[h],n.hasOwnProperty(h)&&null!=p&&!r.hasOwnProperty(h))if("selected"===h)e.selected=!1;else Zc(e,t,h,null,r,p);for(u in r)if(p=r[u],m=n[u],r.hasOwnProperty(u)&&p!==m&&(null!=p||null!=m))if("selected"===u)e.selected=p&&"function"!=typeof p&&"symbol"!=typeof p;else Zc(e,t,u,p,r,m);return;case"img":case"link":case"area":case"base":case"br":case"col":case"embed":case"hr":case"keygen":case"meta":case"param":case"source":case"track":case"wbr":case"menuitem":for(var g in n)p=n[g],n.hasOwnProperty(g)&&null!=p&&!r.hasOwnProperty(g)&&Zc(e,t,g,null,r,p);for(c in r)if(p=r[c],m=n[c],r.hasOwnProperty(c)&&p!==m&&(null!=p||null!=m))switch(c){case"children":case"dangerouslySetInnerHTML":if(null!=p)throw Error(i(137,t));break;default:Zc(e,t,c,p,r,m)}return;default:if(Ct(t)){for(var y in n)p=n[y],n.hasOwnProperty(y)&&void 0!==p&&!r.hasOwnProperty(y)&&Jc(e,t,y,void 0,r,p);for(d in r)p=r[d],m=n[d],!r.hasOwnProperty(d)||p===m||void 0===p&&void 0===m||Jc(e,t,d,p,r,m);return}}for(var b in n)p=n[b],n.hasOwnProperty(b)&&null!=p&&!r.hasOwnProperty(b)&&Zc(e,t,b,null,r,p);for(f in r)p=r[f],m=n[f],!r.hasOwnProperty(f)||p===m||null==p&&null==m||Zc(e,t,f,p,r,m)}(r,e.type,n,t),r[Oe]=t}catch(a){cc(e,e.return,a)}}function ms(e){return 5===e.tag||3===e.tag||26===e.tag||27===e.tag&&pd(e.type)||4===e.tag}function hs(e){e:for(;;){for(;null===e.sibling;){if(null===e.return||ms(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;5!==e.tag&&6!==e.tag&&18!==e.tag;){if(27===e.tag&&pd(e.type))continue e;if(2&e.flags)continue e;if(null===e.child||4===e.tag)continue e;e.child.return=e,e=e.child}if(!(2&e.flags))return e.stateNode}}function gs(e,t,n){var r=e.tag;if(5===r||6===r)e=e.stateNode,t?(9===n.nodeType?n.body:"HTML"===n.nodeName?n.ownerDocument.body:n).insertBefore(e,t):((t=9===n.nodeType?n.body:"HTML"===n.nodeName?n.ownerDocument.body:n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Xc));else if(4!==r&&(27===r&&pd(e.type)&&(n=e.stateNode,t=null),null!==(e=e.child)))for(gs(e,t,n),e=e.sibling;null!==e;)gs(e,t,n),e=e.sibling}function ys(e,t,n){var r=e.tag;if(5===r||6===r)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&(27===r&&pd(e.type)&&(n=e.stateNode),null!==(e=e.child)))for(ys(e,t,n),e=e.sibling;null!==e;)ys(e,t,n),e=e.sibling}function bs(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,a=t.attributes;a.length;)t.removeAttributeNode(a[0]);ed(t,r,n),t[Ne]=e,t[Oe]=n}catch(o){cc(e,e.return,o)}}var vs=!1,ws=!1,ks=!1,Ss="function"==typeof WeakSet?WeakSet:Set,xs=null;function _s(e,t,n){var r=n.flags;switch(n.tag){case 0:case 11:case 15:Fs(e,n),4&r&&is(5,n);break;case 1:if(Fs(e,n),4&r)if(e=n.stateNode,null===t)try{e.componentDidMount()}catch(i){cc(n,n.return,i)}else{var a=gl(n.type,t.memoizedProps);t=t.memoizedState;try{e.componentDidUpdate(a,t,e.__reactInternalSnapshotBeforeUpdate)}catch(l){cc(n,n.return,l)}}64&r&&ss(n),512&r&&cs(n,n.return);break;case 3:if(Fs(e,n),64&r&&null!==(e=n.updateQueue)){if(t=null,null!==n.child)switch(n.child.tag){case 27:case 5:case 1:t=n.child.stateNode}try{po(e,t)}catch(i){cc(n,n.return,i)}}break;case 27:null===t&&4&r&&bs(n);case 26:case 5:Fs(e,n),null===t&&4&r&&fs(n),512&r&&cs(n,n.return);break;case 12:Fs(e,n);break;case 13:Fs(e,n),4&r&&js(e,n),64&r&&(null!==(e=n.memoizedState)&&(null!==(e=e.dehydrated)&&function(e,t){var n=e.ownerDocument;if("$?"!==e.data||"complete"===n.readyState)t();else{var r=function(){t(),n.removeEventListener("DOMContentLoaded",r)};n.addEventListener("DOMContentLoaded",r),e._reactRetry=r}}(e,n=mc.bind(null,n))));break;case 22:if(!(r=null!==n.memoizedState||vs)){t=null!==t&&null!==t.memoizedState||ws,a=vs;var o=ws;vs=r,(ws=t)&&!o?Bs(e,n,!!(8772&n.subtreeFlags)):Fs(e,n),vs=a,ws=o}break;case 30:break;default:Fs(e,n)}}function Es(e){var t=e.alternate;null!==t&&(e.alternate=null,Es(t)),e.child=null,e.deletions=null,e.sibling=null,5===e.tag&&(null!==(t=e.stateNode)&&ze(t)),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}var Cs=null,As=!1;function Ts(e,t,n){for(n=n.child;null!==n;)Ls(e,t,n),n=n.sibling}function Ls(e,t,n){if(de&&"function"==typeof de.onCommitFiberUnmount)try{de.onCommitFiberUnmount(ce,n)}catch(o){}switch(n.tag){case 26:ws||ds(n,t),Ts(e,t,n),n.memoizedState?n.memoizedState.count--:n.stateNode&&(n=n.stateNode).parentNode.removeChild(n);break;case 27:ws||ds(n,t);var r=Cs,a=As;pd(n.type)&&(Cs=n.stateNode,As=!1),Ts(e,t,n),kd(n.stateNode),Cs=r,As=a;break;case 5:ws||ds(n,t);case 6:if(r=Cs,a=As,Cs=null,Ts(e,t,n),As=a,null!==(Cs=r))if(As)try{(9===Cs.nodeType?Cs.body:"HTML"===Cs.nodeName?Cs.ownerDocument.body:Cs).removeChild(n.stateNode)}catch(i){cc(n,t,i)}else try{Cs.removeChild(n.stateNode)}catch(i){cc(n,t,i)}break;case 18:null!==Cs&&(As?(md(9===(e=Cs).nodeType?e.body:"HTML"===e.nodeName?e.ownerDocument.body:e,n.stateNode),Tf(e)):md(Cs,n.stateNode));break;case 4:r=Cs,a=As,Cs=n.stateNode.containerInfo,As=!0,Ts(e,t,n),Cs=r,As=a;break;case 0:case 11:case 14:case 15:ws||ls(2,n,t),ws||ls(4,n,t),Ts(e,t,n);break;case 1:ws||(ds(n,t),"function"==typeof(r=n.stateNode).componentWillUnmount&&us(n,t,r)),Ts(e,t,n);break;case 21:Ts(e,t,n);break;case 22:ws=(r=ws)||null!==n.memoizedState,Ts(e,t,n),ws=r;break;default:Ts(e,t,n)}}function js(e,t){if(null===t.memoizedState&&(null!==(e=t.alternate)&&(null!==(e=e.memoizedState)&&null!==(e=e.dehydrated))))try{Tf(e)}catch(n){cc(t,t.return,n)}}function Ps(e,t){var n=function(e){switch(e.tag){case 13:case 19:var t=e.stateNode;return null===t&&(t=e.stateNode=new Ss),t;case 22:return null===(t=(e=e.stateNode)._retryCache)&&(t=e._retryCache=new Ss),t;default:throw Error(i(435,e.tag))}}(e);t.forEach((function(t){var r=hc.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))}))}function Ns(e,t){var n=t.deletions;if(null!==n)for(var r=0;r<n.length;r++){var a=n[r],o=e,l=t,s=l;e:for(;null!==s;){switch(s.tag){case 27:if(pd(s.type)){Cs=s.stateNode,As=!1;break e}break;case 5:Cs=s.stateNode,As=!1;break e;case 3:case 4:Cs=s.stateNode.containerInfo,As=!0;break e}s=s.return}if(null===Cs)throw Error(i(160));Ls(o,l,a),Cs=null,As=!1,null!==(o=a.alternate)&&(o.return=null),a.return=null}if(13878&t.subtreeFlags)for(t=t.child;null!==t;)Rs(t,e),t=t.sibling}var Os=null;function Rs(e,t){var n=e.alternate,r=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:Ns(t,e),Ms(e),4&r&&(ls(3,e,e.return),is(3,e),ls(5,e,e.return));break;case 1:Ns(t,e),Ms(e),512&r&&(ws||null===n||ds(n,n.return)),64&r&&vs&&(null!==(e=e.updateQueue)&&(null!==(r=e.callbacks)&&(n=e.shared.hiddenCallbacks,e.shared.hiddenCallbacks=null===n?r:n.concat(r))));break;case 26:var a=Os;if(Ns(t,e),Ms(e),512&r&&(ws||null===n||ds(n,n.return)),4&r){var o=null!==n?n.memoizedState:null;if(r=e.memoizedState,null===n)if(null===r)if(null===e.stateNode){e:{r=e.type,n=e.memoizedProps,a=a.ownerDocument||a;t:switch(r){case"title":(!(o=a.getElementsByTagName("title")[0])||o[Be]||o[Ne]||"http://www.w3.org/2000/svg"===o.namespaceURI||o.hasAttribute("itemprop"))&&(o=a.createElement(r),a.head.insertBefore(o,a.querySelector("head > title"))),ed(o,r,n),o[Ne]=e,Ge(o),r=o;break e;case"link":var l=Bd("link","href",a).get(r+(n.href||""));if(l)for(var s=0;s<l.length;s++)if((o=l[s]).getAttribute("href")===(null==n.href||""===n.href?null:n.href)&&o.getAttribute("rel")===(null==n.rel?null:n.rel)&&o.getAttribute("title")===(null==n.title?null:n.title)&&o.getAttribute("crossorigin")===(null==n.crossOrigin?null:n.crossOrigin)){l.splice(s,1);break t}ed(o=a.createElement(r),r,n),a.head.appendChild(o);break;case"meta":if(l=Bd("meta","content",a).get(r+(n.content||"")))for(s=0;s<l.length;s++)if((o=l[s]).getAttribute("content")===(null==n.content?null:""+n.content)&&o.getAttribute("name")===(null==n.name?null:n.name)&&o.getAttribute("property")===(null==n.property?null:n.property)&&o.getAttribute("http-equiv")===(null==n.httpEquiv?null:n.httpEquiv)&&o.getAttribute("charset")===(null==n.charSet?null:n.charSet)){l.splice(s,1);break t}ed(o=a.createElement(r),r,n),a.head.appendChild(o);break;default:throw Error(i(468,r))}o[Ne]=e,Ge(o),r=o}e.stateNode=r}else zd(a,e.type,e.stateNode);else e.stateNode=Rd(a,r,e.memoizedProps);else o!==r?(null===o?null!==n.stateNode&&(n=n.stateNode).parentNode.removeChild(n):o.count--,null===r?zd(a,e.type,e.stateNode):Rd(a,r,e.memoizedProps)):null===r&&null!==e.stateNode&&ps(e,e.memoizedProps,n.memoizedProps)}break;case 27:Ns(t,e),Ms(e),512&r&&(ws||null===n||ds(n,n.return)),null!==n&&4&r&&ps(e,e.memoizedProps,n.memoizedProps);break;case 5:if(Ns(t,e),Ms(e),512&r&&(ws||null===n||ds(n,n.return)),32&e.flags){a=e.stateNode;try{St(a,"")}catch(m){cc(e,e.return,m)}}4&r&&null!=e.stateNode&&ps(e,a=e.memoizedProps,null!==n?n.memoizedProps:a),1024&r&&(ks=!0);break;case 6:if(Ns(t,e),Ms(e),4&r){if(null===e.stateNode)throw Error(i(162));r=e.memoizedProps,n=e.stateNode;try{n.nodeValue=r}catch(m){cc(e,e.return,m)}}break;case 3:if(Id=null,a=Os,Os=_d(t.containerInfo),Ns(t,e),Os=a,Ms(e),4&r&&null!==n&&n.memoizedState.isDehydrated)try{Tf(t.containerInfo)}catch(m){cc(e,e.return,m)}ks&&(ks=!1,Ds(e));break;case 4:r=Os,Os=_d(e.stateNode.containerInfo),Ns(t,e),Ms(e),Os=r;break;case 12:default:Ns(t,e),Ms(e);break;case 13:Ns(t,e),Ms(e),8192&e.child.flags&&null!==e.memoizedState!=(null!==n&&null!==n.memoizedState)&&(ku=te()),4&r&&(null!==(r=e.updateQueue)&&(e.updateQueue=null,Ps(e,r)));break;case 22:a=null!==e.memoizedState;var u=null!==n&&null!==n.memoizedState,c=vs,d=ws;if(vs=c||a,ws=d||u,Ns(t,e),ws=d,vs=c,Ms(e),8192&r)e:for(t=e.stateNode,t._visibility=a?-2&t._visibility:1|t._visibility,a&&(null===n||u||vs||ws||Is(e)),n=null,t=e;;){if(5===t.tag||26===t.tag){if(null===n){u=n=t;try{if(o=u.stateNode,a)"function"==typeof(l=o.style).setProperty?l.setProperty("display","none","important"):l.display="none";else{s=u.stateNode;var f=u.memoizedProps.style,p=null!=f&&f.hasOwnProperty("display")?f.display:null;s.style.display=null==p||"boolean"==typeof p?"":(""+p).trim()}}catch(m){cc(u,u.return,m)}}}else if(6===t.tag){if(null===n){u=t;try{u.stateNode.nodeValue=a?"":u.memoizedProps}catch(m){cc(u,u.return,m)}}}else if((22!==t.tag&&23!==t.tag||null===t.memoizedState||t===e)&&null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break e;for(;null===t.sibling;){if(null===t.return||t.return===e)break e;n===t&&(n=null),t=t.return}n===t&&(n=null),t.sibling.return=t.return,t=t.sibling}4&r&&(null!==(r=e.updateQueue)&&(null!==(n=r.retryQueue)&&(r.retryQueue=null,Ps(e,n))));break;case 19:Ns(t,e),Ms(e),4&r&&(null!==(r=e.updateQueue)&&(e.updateQueue=null,Ps(e,r)));case 30:case 21:}}function Ms(e){var t=e.flags;if(2&t){try{for(var n,r=e.return;null!==r;){if(ms(r)){n=r;break}r=r.return}if(null==n)throw Error(i(160));switch(n.tag){case 27:var a=n.stateNode;ys(e,hs(e),a);break;case 5:var o=n.stateNode;32&n.flags&&(St(o,""),n.flags&=-33),ys(e,hs(e),o);break;case 3:case 4:var l=n.stateNode.containerInfo;gs(e,hs(e),l);break;default:throw Error(i(161))}}catch(s){cc(e,e.return,s)}e.flags&=-3}4096&t&&(e.flags&=-4097)}function Ds(e){if(1024&e.subtreeFlags)for(e=e.child;null!==e;){var t=e;Ds(t),5===t.tag&&1024&t.flags&&t.stateNode.reset(),e=e.sibling}}function Fs(e,t){if(8772&t.subtreeFlags)for(t=t.child;null!==t;)_s(e,t.alternate,t),t=t.sibling}function Is(e){for(e=e.child;null!==e;){var t=e;switch(t.tag){case 0:case 11:case 14:case 15:ls(4,t,t.return),Is(t);break;case 1:ds(t,t.return);var n=t.stateNode;"function"==typeof n.componentWillUnmount&&us(t,t.return,n),Is(t);break;case 27:kd(t.stateNode);case 26:case 5:ds(t,t.return),Is(t);break;case 22:null===t.memoizedState&&Is(t);break;default:Is(t)}e=e.sibling}}function Bs(e,t,n){for(n=n&&!!(8772&t.subtreeFlags),t=t.child;null!==t;){var r=t.alternate,a=e,o=t,i=o.flags;switch(o.tag){case 0:case 11:case 15:Bs(a,o,n),is(4,o);break;case 1:if(Bs(a,o,n),"function"==typeof(a=(r=o).stateNode).componentDidMount)try{a.componentDidMount()}catch(u){cc(r,r.return,u)}if(null!==(a=(r=o).updateQueue)){var l=r.stateNode;try{var s=a.shared.hiddenCallbacks;if(null!==s)for(a.shared.hiddenCallbacks=null,a=0;a<s.length;a++)fo(s[a],l)}catch(u){cc(r,r.return,u)}}n&&64&i&&ss(o),cs(o,o.return);break;case 27:bs(o);case 26:case 5:Bs(a,o,n),n&&null===r&&4&i&&fs(o),cs(o,o.return);break;case 12:Bs(a,o,n);break;case 13:Bs(a,o,n),n&&4&i&&js(a,o);break;case 22:null===o.memoizedState&&Bs(a,o,n),cs(o,o.return);break;case 30:break;default:Bs(a,o,n)}t=t.sibling}}function zs(e,t){var n=null;null!==e&&null!==e.memoizedState&&null!==e.memoizedState.cachePool&&(n=e.memoizedState.cachePool.pool),e=null,null!==t.memoizedState&&null!==t.memoizedState.cachePool&&(e=t.memoizedState.cachePool.pool),e!==n&&(null!=e&&e.refCount++,null!=n&&Ra(n))}function $s(e,t){e=null,null!==t.alternate&&(e=t.alternate.memoizedState.cache),(t=t.memoizedState.cache)!==e&&(t.refCount++,null!=e&&Ra(e))}function Us(e,t,n,r){if(10256&t.subtreeFlags)for(t=t.child;null!==t;)qs(e,t,n,r),t=t.sibling}function qs(e,t,n,r){var a=t.flags;switch(t.tag){case 0:case 11:case 15:Us(e,t,n,r),2048&a&&is(9,t);break;case 1:case 13:default:Us(e,t,n,r);break;case 3:Us(e,t,n,r),2048&a&&(e=null,null!==t.alternate&&(e=t.alternate.memoizedState.cache),(t=t.memoizedState.cache)!==e&&(t.refCount++,null!=e&&Ra(e)));break;case 12:if(2048&a){Us(e,t,n,r),e=t.stateNode;try{var o=t.memoizedProps,i=o.id,l=o.onPostCommit;"function"==typeof l&&l(i,null===t.alternate?"mount":"update",e.passiveEffectDuration,-0)}catch(s){cc(t,t.return,s)}}else Us(e,t,n,r);break;case 23:break;case 22:o=t.stateNode,i=t.alternate,null!==t.memoizedState?2&o._visibility?Us(e,t,n,r):Gs(e,t):2&o._visibility?Us(e,t,n,r):(o._visibility|=2,Hs(e,t,n,r,!!(10256&t.subtreeFlags))),2048&a&&zs(i,t);break;case 24:Us(e,t,n,r),2048&a&&$s(t.alternate,t)}}function Hs(e,t,n,r,a){for(a=a&&!!(10256&t.subtreeFlags),t=t.child;null!==t;){var o=e,i=t,l=n,s=r,u=i.flags;switch(i.tag){case 0:case 11:case 15:Hs(o,i,l,s,a),is(8,i);break;case 23:break;case 22:var c=i.stateNode;null!==i.memoizedState?2&c._visibility?Hs(o,i,l,s,a):Gs(o,i):(c._visibility|=2,Hs(o,i,l,s,a)),a&&2048&u&&zs(i.alternate,i);break;case 24:Hs(o,i,l,s,a),a&&2048&u&&$s(i.alternate,i);break;default:Hs(o,i,l,s,a)}t=t.sibling}}function Gs(e,t){if(10256&t.subtreeFlags)for(t=t.child;null!==t;){var n=e,r=t,a=r.flags;switch(r.tag){case 22:Gs(n,r),2048&a&&zs(r.alternate,r);break;case 24:Gs(n,r),2048&a&&$s(r.alternate,r);break;default:Gs(n,r)}t=t.sibling}}var Vs=8192;function Ws(e){if(e.subtreeFlags&Vs)for(e=e.child;null!==e;)Qs(e),e=e.sibling}function Qs(e){switch(e.tag){case 26:Ws(e),e.flags&Vs&&null!==e.memoizedState&&function(e,t,n){if(null===Ud)throw Error(i(475));var r=Ud;if(!("stylesheet"!==t.type||"string"==typeof n.media&&!1===matchMedia(n.media).matches||4&t.state.loading)){if(null===t.instance){var a=Ld(n.href),o=e.querySelector(jd(a));if(o)return null!==(e=o._p)&&"object"==typeof e&&"function"==typeof e.then&&(r.count++,r=Hd.bind(r),e.then(r,r)),t.state.loading|=4,t.instance=o,void Ge(o);o=e.ownerDocument||e,n=Pd(n),(a=Sd.get(a))&&Dd(n,a),Ge(o=o.createElement("link"));var l=o;l._p=new Promise((function(e,t){l.onload=e,l.onerror=t})),ed(o,"link",n),t.instance=o}null===r.stylesheets&&(r.stylesheets=new Map),r.stylesheets.set(t,e),(e=t.state.preload)&&!(3&t.state.loading)&&(r.count++,t=Hd.bind(r),e.addEventListener("load",t),e.addEventListener("error",t))}}(Os,e.memoizedState,e.memoizedProps);break;case 5:default:Ws(e);break;case 3:case 4:var t=Os;Os=_d(e.stateNode.containerInfo),Ws(e),Os=t;break;case 22:null===e.memoizedState&&(null!==(t=e.alternate)&&null!==t.memoizedState?(t=Vs,Vs=16777216,Ws(e),Vs=t):Ws(e))}}function Ks(e){var t=e.alternate;if(null!==t&&null!==(e=t.child)){t.child=null;do{t=e.sibling,e.sibling=null,e=t}while(null!==e)}}function Ys(e){var t=e.deletions;if(16&e.flags){if(null!==t)for(var n=0;n<t.length;n++){var r=t[n];xs=r,Js(r,e)}Ks(e)}if(10256&e.subtreeFlags)for(e=e.child;null!==e;)Xs(e),e=e.sibling}function Xs(e){switch(e.tag){case 0:case 11:case 15:Ys(e),2048&e.flags&&ls(9,e,e.return);break;case 3:case 12:default:Ys(e);break;case 22:var t=e.stateNode;null!==e.memoizedState&&2&t._visibility&&(null===e.return||13!==e.return.tag)?(t._visibility&=-3,Zs(e)):Ys(e)}}function Zs(e){var t=e.deletions;if(16&e.flags){if(null!==t)for(var n=0;n<t.length;n++){var r=t[n];xs=r,Js(r,e)}Ks(e)}for(e=e.child;null!==e;){switch((t=e).tag){case 0:case 11:case 15:ls(8,t,t.return),Zs(t);break;case 22:2&(n=t.stateNode)._visibility&&(n._visibility&=-3,Zs(t));break;default:Zs(t)}e=e.sibling}}function Js(e,t){for(;null!==xs;){var n=xs;switch(n.tag){case 0:case 11:case 15:ls(8,n,t);break;case 23:case 22:if(null!==n.memoizedState&&null!==n.memoizedState.cachePool){var r=n.memoizedState.cachePool.pool;null!=r&&r.refCount++}break;case 24:Ra(n.memoizedState.cache)}if(null!==(r=n.child))r.return=n,xs=r;else e:for(n=e;null!==xs;){var a=(r=xs).sibling,o=r.return;if(Es(r),r===n){xs=null;break e}if(null!==a){a.return=o,xs=a;break e}xs=o}}}var eu={getCacheForType:function(e){var t=Ca(Na),n=t.data.get(e);return void 0===n&&(n=e(),t.data.set(e,n)),n}},tu="function"==typeof WeakMap?WeakMap:Map,nu=0,ru=null,au=null,ou=0,iu=0,lu=null,su=!1,uu=!1,cu=!1,du=0,fu=0,pu=0,mu=0,hu=0,gu=0,yu=0,bu=null,vu=null,wu=!1,ku=0,Su=1/0,xu=null,_u=null,Eu=0,Cu=null,Au=null,Tu=0,Lu=0,ju=null,Pu=null,Nu=0,Ou=null;function Ru(){if(2&nu&&0!==ou)return ou&-ou;if(null!==R.T){return 0!==Fa?Fa:Lc()}return je()}function Mu(){0===gu&&(gu=536870912&ou&&!oa?536870912:Se());var e=al.current;return null!==e&&(e.flags|=32),gu}function Du(e,t,n){(e!==ru||2!==iu&&9!==iu)&&null===e.cancelPendingCommit||(qu(e,0),zu(e,ou,gu,!1)),Ee(e,n),2&nu&&e===ru||(e===ru&&(!(2&nu)&&(mu|=n),4===fu&&zu(e,ou,gu,!1)),Sc(e))}function Fu(e,t,n){if(6&nu)throw Error(i(327));for(var r=!n&&!(124&t)&&0===(t&e.expiredLanes)||we(e,t),a=r?function(e,t){var n=nu;nu|=2;var r=Gu(),a=Vu();ru!==e||ou!==t?(xu=null,Su=te()+500,qu(e,t)):uu=we(e,t);e:for(;;)try{if(0!==iu&&null!==au){t=au;var o=lu;t:switch(iu){case 1:iu=0,lu=null,Ju(e,t,o,1);break;case 2:case 9:if(Ka(o)){iu=0,lu=null,Zu(t);break}t=function(){2!==iu&&9!==iu||ru!==e||(iu=7),Sc(e)},o.then(t,t);break e;case 3:iu=7;break e;case 4:iu=5;break e;case 7:Ka(o)?(iu=0,lu=null,Zu(t)):(iu=0,lu=null,Ju(e,t,o,7));break;case 5:var l=null;switch(au.tag){case 26:l=au.memoizedState;case 5:case 27:var s=au;if(!l||$d(l)){iu=0,lu=null;var u=s.sibling;if(null!==u)au=u;else{var c=s.return;null!==c?(au=c,ec(c)):au=null}break t}}iu=0,lu=null,Ju(e,t,o,5);break;case 6:iu=0,lu=null,Ju(e,t,o,6);break;case 8:Uu(),fu=6;break e;default:throw Error(i(462))}}Yu();break}catch(d){Hu(e,d)}return ba=ya=null,R.H=r,R.A=a,nu=n,null!==au?0:(ru=null,ou=0,Tr(),fu)}(e,t):Qu(e,t,!0),o=r;;){if(0===a){uu&&!r&&zu(e,t,0,!1);break}if(n=e.current.alternate,!o||Bu(n)){if(2===a){if(o=t,e.errorRecoveryDisabledLanes&o)var l=0;else l=0!==(l=-536870913&e.pendingLanes)?l:536870912&l?536870912:0;if(0!==l){t=l;e:{var s=e;a=bu;var u=s.current.memoizedState.isDehydrated;if(u&&(qu(s,l).flags|=256),2!==(l=Qu(s,l,!1))){if(cu&&!u){s.errorRecoveryDisabledLanes|=o,mu|=o,a=4;break e}o=vu,vu=a,null!==o&&(null===vu?vu=o:vu.push.apply(vu,o))}a=l}if(o=!1,2!==a)continue}}if(1===a){qu(e,0),zu(e,t,0,!0);break}e:{switch(r=e,o=a){case 0:case 1:throw Error(i(345));case 4:if((4194048&t)!==t)break;case 6:zu(r,t,gu,!su);break e;case 2:vu=null;break;case 3:case 5:break;default:throw Error(i(329))}if((62914560&t)===t&&10<(a=ku+300-te())){if(zu(r,t,gu,!su),0!==ve(r,0,!0))break e;r.timeoutHandle=sd(Iu.bind(null,r,n,vu,xu,wu,t,gu,mu,yu,su,o,2,-0,0),a)}else Iu(r,n,vu,xu,wu,t,gu,mu,yu,su,o,0,-0,0)}break}a=Qu(e,t,!1),o=!1}Sc(e)}function Iu(e,t,n,r,a,o,l,s,u,c,d,f,p,m){if(e.timeoutHandle=-1,(8192&(f=t.subtreeFlags)||!(16785408&~f))&&(Ud={stylesheets:null,count:0,unsuspend:qd},Qs(t),null!==(f=function(){if(null===Ud)throw Error(i(475));var e=Ud;return e.stylesheets&&0===e.count&&Vd(e,e.stylesheets),0<e.count?function(t){var n=setTimeout((function(){if(e.stylesheets&&Vd(e,e.stylesheets),e.unsuspend){var t=e.unsuspend;e.unsuspend=null,t()}}),6e4);return e.unsuspend=t,function(){e.unsuspend=null,clearTimeout(n)}}:null}())))return e.cancelPendingCommit=f(nc.bind(null,e,t,o,n,r,a,l,s,u,d,1,p,m)),void zu(e,o,l,!c);nc(e,t,o,n,r,a,l,s,u)}function Bu(e){for(var t=e;;){var n=t.tag;if((0===n||11===n||15===n)&&16384&t.flags&&(null!==(n=t.updateQueue)&&null!==(n=n.stores)))for(var r=0;r<n.length;r++){var a=n[r],o=a.getSnapshot;a=a.value;try{if(!Kn(o(),a))return!1}catch(i){return!1}}if(n=t.child,16384&t.subtreeFlags&&null!==n)n.return=t,t=n;else{if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}function zu(e,t,n,r){t&=~hu,t&=~mu,e.suspendedLanes|=t,e.pingedLanes&=~t,r&&(e.warmLanes|=t),r=e.expirationTimes;for(var a=t;0<a;){var o=31-pe(a),i=1<<o;r[o]=-1,a&=~i}0!==n&&Ce(e,n,t)}function $u(){return!!(6&nu)||(xc(0,!1),!1)}function Uu(){if(null!==au){if(0===iu)var e=au.return;else ba=ya=null,Io(e=au),Ki=null,Yi=0,e=au;for(;null!==e;)os(e.alternate,e),e=e.return;au=null}}function qu(e,t){var n=e.timeoutHandle;-1!==n&&(e.timeoutHandle=-1,ud(n)),null!==(n=e.cancelPendingCommit)&&(e.cancelPendingCommit=null,n()),Uu(),ru=e,au=n=Ir(e.current,null),ou=t,iu=0,lu=null,su=!1,uu=we(e,t),cu=!1,yu=gu=hu=mu=pu=fu=0,vu=bu=null,wu=!1,8&t&&(t|=32&t);var r=e.entangledLanes;if(0!==r)for(e=e.entanglements,r&=t;0<r;){var a=31-pe(r),o=1<<a;t|=e[a],r&=~o}return du=t,Tr(),n}function Hu(e,t){wo=null,R.H=Gi,t===Ga||t===Wa?(t=Ja(),iu=3):t===Va?(t=Ja(),iu=4):iu=t===Cl?8:null!==t&&"object"==typeof t&&"function"==typeof t.then?6:1,lu=t,null===au&&(fu=1,kl(e,_r(t,e.current)))}function Gu(){var e=R.H;return R.H=Gi,null===e?Gi:e}function Vu(){var e=R.A;return R.A=eu,e}function Wu(){fu=4,su||(4194048&ou)!==ou&&null!==al.current||(uu=!0),!(134217727&pu)&&!(134217727&mu)||null===ru||zu(ru,ou,gu,!1)}function Qu(e,t,n){var r=nu;nu|=2;var a=Gu(),o=Vu();ru===e&&ou===t||(xu=null,qu(e,t)),t=!1;var i=fu;e:for(;;)try{if(0!==iu&&null!==au){var l=au,s=lu;switch(iu){case 8:Uu(),i=6;break e;case 3:case 2:case 9:case 6:null===al.current&&(t=!0);var u=iu;if(iu=0,lu=null,Ju(e,l,s,u),n&&uu){i=0;break e}break;default:u=iu,iu=0,lu=null,Ju(e,l,s,u)}}Ku(),i=fu;break}catch(c){Hu(e,c)}return t&&e.shellSuspendCounter++,ba=ya=null,nu=r,R.H=a,R.A=o,null===au&&(ru=null,ou=0,Tr()),i}function Ku(){for(;null!==au;)Xu(au)}function Yu(){for(;null!==au&&!J();)Xu(au)}function Xu(e){var t=Xl(e.alternate,e,du);e.memoizedProps=e.pendingProps,null===t?ec(e):au=t}function Zu(e){var t=e,n=t.alternate;switch(t.tag){case 15:case 0:t=Dl(n,t,t.pendingProps,t.type,void 0,ou);break;case 11:t=Dl(n,t,t.pendingProps,t.type.render,t.ref,ou);break;case 5:Io(t);default:os(n,t),t=Xl(n,t=au=Br(t,du),du)}e.memoizedProps=e.pendingProps,null===t?ec(e):au=t}function Ju(e,t,n,r){ba=ya=null,Io(t),Ki=null,Yi=0;var a=t.return;try{if(function(e,t,n,r,a){if(n.flags|=32768,null!==r&&"object"==typeof r&&"function"==typeof r.then){if(null!==(t=n.alternate)&&xa(t,n,a,!0),null!==(n=al.current)){switch(n.tag){case 13:return null===ol?Wu():null===n.alternate&&0===fu&&(fu=3),n.flags&=-257,n.flags|=65536,n.lanes=a,r===Qa?n.flags|=16384:(null===(t=n.updateQueue)?n.updateQueue=new Set([r]):t.add(r),dc(e,r,a)),!1;case 22:return n.flags|=65536,r===Qa?n.flags|=16384:(null===(t=n.updateQueue)?(t={transitions:null,markerInstances:null,retryQueue:new Set([r])},n.updateQueue=t):null===(n=t.retryQueue)?t.retryQueue=new Set([r]):n.add(r),dc(e,r,a)),!1}throw Error(i(435,n.tag))}return dc(e,r,a),Wu(),!1}if(oa)return null!==(t=al.current)?(!(65536&t.flags)&&(t.flags|=256),t.flags|=65536,t.lanes=a,r!==sa&&ha(_r(e=Error(i(422),{cause:r}),n))):(r!==sa&&ha(_r(t=Error(i(423),{cause:r}),n)),(e=e.current.alternate).flags|=65536,a&=-a,e.lanes|=a,r=_r(r,n),lo(e,a=xl(e.stateNode,r,a)),4!==fu&&(fu=2)),!1;var o=Error(i(520),{cause:r});if(o=_r(o,n),null===bu?bu=[o]:bu.push(o),4!==fu&&(fu=2),null===t)return!0;r=_r(r,n),n=t;do{switch(n.tag){case 3:return n.flags|=65536,e=a&-a,n.lanes|=e,lo(n,e=xl(n.stateNode,r,e)),!1;case 1:if(t=n.type,o=n.stateNode,!(128&n.flags||"function"!=typeof t.getDerivedStateFromError&&(null===o||"function"!=typeof o.componentDidCatch||null!==_u&&_u.has(o))))return n.flags|=65536,a&=-a,n.lanes|=a,El(a=_l(a),e,n,r),lo(n,a),!1}n=n.return}while(null!==n);return!1}(e,a,t,n,ou))return fu=1,kl(e,_r(n,e.current)),void(au=null)}catch(o){if(null!==a)throw au=a,o;return fu=1,kl(e,_r(n,e.current)),void(au=null)}32768&t.flags?(oa||1===r?e=!0:uu||536870912&ou?e=!1:(su=e=!0,(2===r||9===r||3===r||6===r)&&(null!==(r=al.current)&&13===r.tag&&(r.flags|=16384))),tc(t,e)):ec(t)}function ec(e){var t=e;do{if(32768&t.flags)return void tc(t,su);e=t.return;var n=rs(t.alternate,t,du);if(null!==n)return void(au=n);if(null!==(t=t.sibling))return void(au=t);au=t=e}while(null!==t);0===fu&&(fu=5)}function tc(e,t){do{var n=as(e.alternate,e);if(null!==n)return n.flags&=32767,void(au=n);if(null!==(n=e.return)&&(n.flags|=32768,n.subtreeFlags=0,n.deletions=null),!t&&null!==(e=e.sibling))return void(au=e);au=e=n}while(null!==e);fu=6,au=null}function nc(e,t,n,r,a,o,l,s,u){e.cancelPendingCommit=null;do{lc()}while(0!==Eu);if(6&nu)throw Error(i(327));if(null!==t){if(t===e.current)throw Error(i(177));if(o=t.lanes|t.childLanes,function(e,t,n,r,a,o){var i=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var l=e.entanglements,s=e.expirationTimes,u=e.hiddenUpdates;for(n=i&~n;0<n;){var c=31-pe(n),d=1<<c;l[c]=0,s[c]=-1;var f=u[c];if(null!==f)for(u[c]=null,c=0;c<f.length;c++){var p=f[c];null!==p&&(p.lane&=-536870913)}n&=~d}0!==r&&Ce(e,r,0),0!==o&&0===a&&0!==e.tag&&(e.suspendedLanes|=o&~(i&~t))}(e,n,o|=Ar,l,s,u),e===ru&&(au=ru=null,ou=0),Au=t,Cu=e,Tu=n,Lu=o,ju=a,Pu=r,10256&t.subtreeFlags||10256&t.flags?(e.callbackNode=null,e.callbackPriority=0,X(oe,(function(){return sc(),null}))):(e.callbackNode=null,e.callbackPriority=0),r=!!(13878&t.flags),13878&t.subtreeFlags||r){r=R.T,R.T=null,a=M.p,M.p=2,l=nu,nu|=4;try{!function(e,t){if(e=e.containerInfo,td=nf,tr(e=er(e))){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{var r=(n=(n=e.ownerDocument)&&n.defaultView||window).getSelection&&n.getSelection();if(r&&0!==r.rangeCount){n=r.anchorNode;var a=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch(g){n=null;break e}var l=0,s=-1,u=-1,c=0,d=0,f=e,p=null;t:for(;;){for(var m;f!==n||0!==a&&3!==f.nodeType||(s=l+a),f!==o||0!==r&&3!==f.nodeType||(u=l+r),3===f.nodeType&&(l+=f.nodeValue.length),null!==(m=f.firstChild);)p=f,f=m;for(;;){if(f===e)break t;if(p===n&&++c===a&&(s=l),p===o&&++d===r&&(u=l),null!==(m=f.nextSibling))break;p=(f=p).parentNode}f=m}n=-1===s||-1===u?null:{start:s,end:u}}else n=null}n=n||{start:0,end:0}}else n=null;for(nd={focusedElem:e,selectionRange:n},nf=!1,xs=t;null!==xs;)if(e=(t=xs).child,1024&t.subtreeFlags&&null!==e)e.return=t,xs=e;else for(;null!==xs;){switch(o=(t=xs).alternate,e=t.flags,t.tag){case 0:case 11:case 15:case 5:case 26:case 27:case 6:case 4:case 17:break;case 1:if(1024&e&&null!==o){e=void 0,n=t,a=o.memoizedProps,o=o.memoizedState,r=n.stateNode;try{var h=gl(n.type,a,(n.elementType,n.type));e=r.getSnapshotBeforeUpdate(h,o),r.__reactInternalSnapshotBeforeUpdate=e}catch(y){cc(n,n.return,y)}}break;case 3:if(1024&e)if(9===(n=(e=t.stateNode.containerInfo).nodeType))hd(e);else if(1===n)switch(e.nodeName){case"HEAD":case"HTML":case"BODY":hd(e);break;default:e.textContent=""}break;default:if(1024&e)throw Error(i(163))}if(null!==(e=t.sibling)){e.return=t.return,xs=e;break}xs=t.return}}(e,t)}finally{nu=l,M.p=a,R.T=r}}Eu=1,rc(),ac(),oc()}}function rc(){if(1===Eu){Eu=0;var e=Cu,t=Au,n=!!(13878&t.flags);if(13878&t.subtreeFlags||n){n=R.T,R.T=null;var r=M.p;M.p=2;var a=nu;nu|=4;try{Rs(t,e);var o=nd,i=er(e.containerInfo),l=o.focusedElem,s=o.selectionRange;if(i!==l&&l&&l.ownerDocument&&Jn(l.ownerDocument.documentElement,l)){if(null!==s&&tr(l)){var u=s.start,c=s.end;if(void 0===c&&(c=u),"selectionStart"in l)l.selectionStart=u,l.selectionEnd=Math.min(c,l.value.length);else{var d=l.ownerDocument||document,f=d&&d.defaultView||window;if(f.getSelection){var p=f.getSelection(),m=l.textContent.length,h=Math.min(s.start,m),g=void 0===s.end?h:Math.min(s.end,m);!p.extend&&h>g&&(i=g,g=h,h=i);var y=Zn(l,h),b=Zn(l,g);if(y&&b&&(1!==p.rangeCount||p.anchorNode!==y.node||p.anchorOffset!==y.offset||p.focusNode!==b.node||p.focusOffset!==b.offset)){var v=d.createRange();v.setStart(y.node,y.offset),p.removeAllRanges(),h>g?(p.addRange(v),p.extend(b.node,b.offset)):(v.setEnd(b.node,b.offset),p.addRange(v))}}}}for(d=[],p=l;p=p.parentNode;)1===p.nodeType&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for("function"==typeof l.focus&&l.focus(),l=0;l<d.length;l++){var w=d[l];w.element.scrollLeft=w.left,w.element.scrollTop=w.top}}nf=!!td,nd=td=null}finally{nu=a,M.p=r,R.T=n}}e.current=t,Eu=2}}function ac(){if(2===Eu){Eu=0;var e=Cu,t=Au,n=!!(8772&t.flags);if(8772&t.subtreeFlags||n){n=R.T,R.T=null;var r=M.p;M.p=2;var a=nu;nu|=4;try{_s(e,t.alternate,t)}finally{nu=a,M.p=r,R.T=n}}Eu=3}}function oc(){if(4===Eu||3===Eu){Eu=0,ee();var e=Cu,t=Au,n=Tu,r=Pu;10256&t.subtreeFlags||10256&t.flags?Eu=5:(Eu=0,Au=Cu=null,ic(e,e.pendingLanes));var a=e.pendingLanes;if(0===a&&(_u=null),Le(n),t=t.stateNode,de&&"function"==typeof de.onCommitFiberRoot)try{de.onCommitFiberRoot(ce,t,void 0,!(128&~t.current.flags))}catch(s){}if(null!==r){t=R.T,a=M.p,M.p=2,R.T=null;try{for(var o=e.onRecoverableError,i=0;i<r.length;i++){var l=r[i];o(l.value,{componentStack:l.stack})}}finally{R.T=t,M.p=a}}3&Tu&&lc(),Sc(e),a=e.pendingLanes,4194090&n&&42&a?e===Ou?Nu++:(Nu=0,Ou=e):Nu=0,xc(0,!1)}}function ic(e,t){0===(e.pooledCacheLanes&=t)&&(null!=(t=e.pooledCache)&&(e.pooledCache=null,Ra(t)))}function lc(e){return rc(),ac(),oc(),sc()}function sc(){if(5!==Eu)return!1;var e=Cu,t=Lu;Lu=0;var n=Le(Tu),r=R.T,a=M.p;try{M.p=32>n?32:n,R.T=null,n=ju,ju=null;var o=Cu,l=Tu;if(Eu=0,Au=Cu=null,Tu=0,6&nu)throw Error(i(331));var s=nu;if(nu|=4,Xs(o.current),qs(o,o.current,l,n),nu=s,xc(0,!1),de&&"function"==typeof de.onPostCommitFiberRoot)try{de.onPostCommitFiberRoot(ce,o)}catch(u){}return!0}finally{M.p=a,R.T=r,ic(e,t)}}function uc(e,t,n){t=_r(n,t),null!==(e=oo(e,t=xl(e.stateNode,t,2),2))&&(Ee(e,2),Sc(e))}function cc(e,t,n){if(3===e.tag)uc(e,e,n);else for(;null!==t;){if(3===t.tag){uc(t,e,n);break}if(1===t.tag){var r=t.stateNode;if("function"==typeof t.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===_u||!_u.has(r))){e=_r(n,e),null!==(r=oo(t,n=_l(2),2))&&(El(n,r,t,e),Ee(r,2),Sc(r));break}}t=t.return}}function dc(e,t,n){var r=e.pingCache;if(null===r){r=e.pingCache=new tu;var a=new Set;r.set(t,a)}else void 0===(a=r.get(t))&&(a=new Set,r.set(t,a));a.has(n)||(cu=!0,a.add(n),e=fc.bind(null,e,t,n),t.then(e,e))}function fc(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,ru===e&&(ou&n)===n&&(4===fu||3===fu&&(62914560&ou)===ou&&300>te()-ku?!(2&nu)&&qu(e,0):hu|=n,yu===ou&&(yu=0)),Sc(e)}function pc(e,t){0===t&&(t=xe()),null!==(e=Pr(e,t))&&(Ee(e,t),Sc(e))}function mc(e){var t=e.memoizedState,n=0;null!==t&&(n=t.retryLane),pc(e,n)}function hc(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,a=e.memoizedState;null!==a&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}null!==r&&r.delete(t),pc(e,n)}var gc=null,yc=null,bc=!1,vc=!1,wc=!1,kc=0;function Sc(e){e!==yc&&null===e.next&&(null===yc?gc=yc=e:yc=yc.next=e),vc=!0,bc||(bc=!0,dd((function(){6&nu?X(re,_c):Ec()})))}function xc(e,t){if(!wc&&vc){wc=!0;do{for(var n=!1,r=gc;null!==r;){if(!t)if(0!==e){var a=r.pendingLanes;if(0===a)var o=0;else{var i=r.suspendedLanes,l=r.pingedLanes;o=(1<<31-pe(42|e)+1)-1,o=201326741&(o&=a&~(i&~l))?201326741&o|1:o?2|o:0}0!==o&&(n=!0,Tc(r,o))}else o=ou,!(3&(o=ve(r,r===ru?o:0,null!==r.cancelPendingCommit||-1!==r.timeoutHandle)))||we(r,o)||(n=!0,Tc(r,o));r=r.next}}while(n);wc=!1}}function _c(){Ec()}function Ec(){vc=bc=!1;var e=0;0!==kc&&(function(){var e=window.event;if(e&&"popstate"===e.type)return e!==ld&&(ld=e,!0);return ld=null,!1}()&&(e=kc),kc=0);for(var t=te(),n=null,r=gc;null!==r;){var a=r.next,o=Cc(r,t);0===o?(r.next=null,null===n?gc=a:n.next=a,null===a&&(yc=n)):(n=r,(0!==e||3&o)&&(vc=!0)),r=a}xc(e,!1)}function Cc(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,a=e.expirationTimes,o=-62914561&e.pendingLanes;0<o;){var i=31-pe(o),l=1<<i,s=a[i];-1===s?0!==(l&n)&&0===(l&r)||(a[i]=ke(l,t)):s<=t&&(e.expiredLanes|=l),o&=~l}if(n=ou,n=ve(e,e===(t=ru)?n:0,null!==e.cancelPendingCommit||-1!==e.timeoutHandle),r=e.callbackNode,0===n||e===t&&(2===iu||9===iu)||null!==e.cancelPendingCommit)return null!==r&&null!==r&&Z(r),e.callbackNode=null,e.callbackPriority=0;if(!(3&n)||we(e,n)){if((t=n&-n)===e.callbackPriority)return t;switch(null!==r&&Z(r),Le(n)){case 2:case 8:n=ae;break;case 32:default:n=oe;break;case 268435456:n=le}return r=Ac.bind(null,e),n=X(n,r),e.callbackPriority=t,e.callbackNode=n,t}return null!==r&&null!==r&&Z(r),e.callbackPriority=2,e.callbackNode=null,2}function Ac(e,t){if(0!==Eu&&5!==Eu)return e.callbackNode=null,e.callbackPriority=0,null;var n=e.callbackNode;if(lc()&&e.callbackNode!==n)return null;var r=ou;return 0===(r=ve(e,e===ru?r:0,null!==e.cancelPendingCommit||-1!==e.timeoutHandle))?null:(Fu(e,r,t),Cc(e,te()),null!=e.callbackNode&&e.callbackNode===n?Ac.bind(null,e):null)}function Tc(e,t){if(lc())return null;Fu(e,t,!0)}function Lc(){return 0===kc&&(kc=Se()),kc}function jc(e){return null==e||"symbol"==typeof e||"boolean"==typeof e?null:"function"==typeof e?e:Lt(""+e)}function Pc(e,t){var n=t.ownerDocument.createElement("input");return n.name=t.name,n.value=t.value,e.id&&n.setAttribute("form",e.id),t.parentNode.insertBefore(n,t),e=new FormData(e),n.parentNode.removeChild(n),e}for(var Nc=0;Nc<kr.length;Nc++){var Oc=kr[Nc];Sr(Oc.toLowerCase(),"on"+(Oc[0].toUpperCase()+Oc.slice(1)))}Sr(pr,"onAnimationEnd"),Sr(mr,"onAnimationIteration"),Sr(hr,"onAnimationStart"),Sr("dblclick","onDoubleClick"),Sr("focusin","onFocus"),Sr("focusout","onBlur"),Sr(gr,"onTransitionRun"),Sr(yr,"onTransitionStart"),Sr(br,"onTransitionCancel"),Sr(vr,"onTransitionEnd"),Ke("onMouseEnter",["mouseout","mouseover"]),Ke("onMouseLeave",["mouseout","mouseover"]),Ke("onPointerEnter",["pointerout","pointerover"]),Ke("onPointerLeave",["pointerout","pointerover"]),Qe("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),Qe("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),Qe("onBeforeInput",["compositionend","keypress","textInput","paste"]),Qe("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),Qe("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),Qe("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Rc="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Mc=new Set("beforetoggle cancel close invalid load scroll scrollend toggle".split(" ").concat(Rc));function Dc(e,t){t=!!(4&t);for(var n=0;n<e.length;n++){var r=e[n],a=r.event;r=r.listeners;e:{var o=void 0;if(t)for(var i=r.length-1;0<=i;i--){var l=r[i],s=l.instance,u=l.currentTarget;if(l=l.listener,s!==o&&a.isPropagationStopped())break e;o=l,a.currentTarget=u;try{o(a)}catch(c){yl(c)}a.currentTarget=null,o=s}else for(i=0;i<r.length;i++){if(s=(l=r[i]).instance,u=l.currentTarget,l=l.listener,s!==o&&a.isPropagationStopped())break e;o=l,a.currentTarget=u;try{o(a)}catch(c){yl(c)}a.currentTarget=null,o=s}}}}function Fc(e,t){var n=t[Me];void 0===n&&(n=t[Me]=new Set);var r=e+"__bubble";n.has(r)||($c(t,e,2,!1),n.add(r))}function Ic(e,t,n){var r=0;t&&(r|=4),$c(n,e,r,t)}var Bc="_reactListening"+Math.random().toString(36).slice(2);function zc(e){if(!e[Bc]){e[Bc]=!0,Ve.forEach((function(t){"selectionchange"!==t&&(Mc.has(t)||Ic(t,!1,e),Ic(t,!0,e))}));var t=9===e.nodeType?e:e.ownerDocument;null===t||t[Bc]||(t[Bc]=!0,Ic("selectionchange",!1,t))}}function $c(e,t,n,r){switch(cf(t)){case 2:var a=rf;break;case 8:a=af;break;default:a=of}n=a.bind(null,t,n,e),a=void 0,!Bt||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(a=!0),r?void 0!==a?e.addEventListener(t,n,{capture:!0,passive:a}):e.addEventListener(t,n,!0):void 0!==a?e.addEventListener(t,n,{passive:a}):e.addEventListener(t,n,!1)}function Uc(e,t,n,r,a){var o=r;if(!(1&t||2&t||null===r))e:for(;;){if(null===r)return;var i=r.tag;if(3===i||4===i){var l=r.stateNode.containerInfo;if(l===a)break;if(4===i)for(i=r.return;null!==i;){var u=i.tag;if((3===u||4===u)&&i.stateNode.containerInfo===a)return;i=i.return}for(;null!==l;){if(null===(i=$e(l)))return;if(5===(u=i.tag)||6===u||26===u||27===u){r=o=i;continue e}l=l.parentNode}}r=r.return}Dt((function(){var r=o,a=Pt(n),i=[];e:{var l=wr.get(e);if(void 0!==l){var u=Jt,c=e;switch(e){case"keypress":if(0===Gt(n))break e;case"keydown":case"keyup":u=hn;break;case"focusin":c="focus",u=on;break;case"focusout":c="blur",u=on;break;case"beforeblur":case"afterblur":u=on;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":u=rn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":u=an;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":u=yn;break;case pr:case mr:case hr:u=ln;break;case vr:u=bn;break;case"scroll":case"scrollend":u=tn;break;case"wheel":u=vn;break;case"copy":case"cut":case"paste":u=sn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":u=gn;break;case"toggle":case"beforetoggle":u=wn}var d=!!(4&t),f=!d&&("scroll"===e||"scrollend"===e),p=d?null!==l?l+"Capture":null:l;d=[];for(var m,h=r;null!==h;){var g=h;if(m=g.stateNode,5!==(g=g.tag)&&26!==g&&27!==g||null===m||null===p||null!=(g=Ft(h,p))&&d.push(qc(h,g,m)),f)break;h=h.return}0<d.length&&(l=new u(l,c,null,n,a),i.push({event:l,listeners:d}))}}if(!(7&t)){if(u="mouseout"===e||"pointerout"===e,(!(l="mouseover"===e||"pointerover"===e)||n===jt||!(c=n.relatedTarget||n.fromElement)||!$e(c)&&!c[Re])&&(u||l)&&(l=a.window===a?a:(l=a.ownerDocument)?l.defaultView||l.parentWindow:window,u?(u=r,null!==(c=(c=n.relatedTarget||n.toElement)?$e(c):null)&&(f=s(c),d=c.tag,c!==f||5!==d&&27!==d&&6!==d)&&(c=null)):(u=null,c=r),u!==c)){if(d=rn,g="onMouseLeave",p="onMouseEnter",h="mouse","pointerout"!==e&&"pointerover"!==e||(d=gn,g="onPointerLeave",p="onPointerEnter",h="pointer"),f=null==u?l:qe(u),m=null==c?l:qe(c),(l=new d(g,h+"leave",u,n,a)).target=f,l.relatedTarget=m,g=null,$e(a)===r&&((d=new d(p,h+"enter",c,n,a)).target=m,d.relatedTarget=f,g=d),f=g,u&&c)e:{for(p=c,h=0,m=d=u;m;m=Gc(m))h++;for(m=0,g=p;g;g=Gc(g))m++;for(;0<h-m;)d=Gc(d),h--;for(;0<m-h;)p=Gc(p),m--;for(;h--;){if(d===p||null!==p&&d===p.alternate)break e;d=Gc(d),p=Gc(p)}d=null}else d=null;null!==u&&Vc(i,l,u,d,!1),null!==c&&null!==f&&Vc(i,f,c,d,!0)}if("select"===(u=(l=r?qe(r):window).nodeName&&l.nodeName.toLowerCase())||"input"===u&&"file"===l.type)var y=In;else if(Nn(l))if(Bn)y=Qn;else{y=Vn;var b=Gn}else!(u=l.nodeName)||"input"!==u.toLowerCase()||"checkbox"!==l.type&&"radio"!==l.type?r&&Ct(r.elementType)&&(y=In):y=Wn;switch(y&&(y=y(e,r))?On(i,y,n,a):(b&&b(e,l,r),"focusout"===e&&r&&"number"===l.type&&null!=r.memoizedProps.value&&bt(l,"number",l.value)),b=r?qe(r):window,e){case"focusin":(Nn(b)||"true"===b.contentEditable)&&(rr=b,ar=r,or=null);break;case"focusout":or=ar=rr=null;break;case"mousedown":ir=!0;break;case"contextmenu":case"mouseup":case"dragend":ir=!1,lr(i,n,a);break;case"selectionchange":if(nr)break;case"keydown":case"keyup":lr(i,n,a)}var v;if(Sn)e:{switch(e){case"compositionstart":var w="onCompositionStart";break e;case"compositionend":w="onCompositionEnd";break e;case"compositionupdate":w="onCompositionUpdate";break e}w=void 0}else jn?Tn(e,n)&&(w="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(w="onCompositionStart");w&&(En&&"ko"!==n.locale&&(jn||"onCompositionStart"!==w?"onCompositionEnd"===w&&jn&&(v=Ht()):(Ut="value"in($t=a)?$t.value:$t.textContent,jn=!0)),0<(b=Hc(r,w)).length&&(w=new un(w,e,null,n,a),i.push({event:w,listeners:b}),v?w.data=v:null!==(v=Ln(n))&&(w.data=v))),(v=_n?function(e,t){switch(e){case"compositionend":return Ln(t);case"keypress":return 32!==t.which?null:(An=!0,Cn);case"textInput":return(e=t.data)===Cn&&An?null:e;default:return null}}(e,n):function(e,t){if(jn)return"compositionend"===e||!Sn&&Tn(e,t)?(e=Ht(),qt=Ut=$t=null,jn=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return En&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(w=Hc(r,"onBeforeInput")).length&&(b=new un("onBeforeInput","beforeinput",null,n,a),i.push({event:b,listeners:w}),b.data=v)),function(e,t,n,r,a){if("submit"===t&&n&&n.stateNode===a){var o=jc((a[Oe]||null).action),i=r.submitter;i&&null!==(t=(t=i[Oe]||null)?jc(t.formAction):i.getAttribute("formAction"))&&(o=t,i=null);var l=new Jt("action","action",null,r,a);e.push({event:l,listeners:[{instance:null,listener:function(){if(r.defaultPrevented){if(0!==kc){var e=i?Pc(a,i):new FormData(a);Pi(n,{pending:!0,data:e,method:a.method,action:o},null,e)}}else"function"==typeof o&&(l.preventDefault(),e=i?Pc(a,i):new FormData(a),Pi(n,{pending:!0,data:e,method:a.method,action:o},o,e))},currentTarget:a}]})}}(i,e,r,n,a)}Dc(i,t)}))}function qc(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Hc(e,t){for(var n=t+"Capture",r=[];null!==e;){var a=e,o=a.stateNode;if(5!==(a=a.tag)&&26!==a&&27!==a||null===o||(null!=(a=Ft(e,n))&&r.unshift(qc(e,a,o)),null!=(a=Ft(e,t))&&r.push(qc(e,a,o))),3===e.tag)return r;e=e.return}return[]}function Gc(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag&&27!==e.tag);return e||null}function Vc(e,t,n,r,a){for(var o=t._reactName,i=[];null!==n&&n!==r;){var l=n,s=l.alternate,u=l.stateNode;if(l=l.tag,null!==s&&s===r)break;5!==l&&26!==l&&27!==l||null===u||(s=u,a?null!=(u=Ft(n,o))&&i.unshift(qc(n,u,s)):a||null!=(u=Ft(n,o))&&i.push(qc(n,u,s))),n=n.return}0!==i.length&&e.push({event:t,listeners:i})}var Wc=/\r\n?/g,Qc=/\u0000|\uFFFD/g;function Kc(e){return("string"==typeof e?e:""+e).replace(Wc,"\n").replace(Qc,"")}function Yc(e,t){return t=Kc(t),Kc(e)===t}function Xc(){}function Zc(e,t,n,r,a,o){switch(n){case"children":"string"==typeof r?"body"===t||"textarea"===t&&""===r||St(e,r):("number"==typeof r||"bigint"==typeof r)&&"body"!==t&&St(e,""+r);break;case"className":nt(e,"class",r);break;case"tabIndex":nt(e,"tabindex",r);break;case"dir":case"role":case"viewBox":case"width":case"height":nt(e,n,r);break;case"style":Et(e,r,o);break;case"data":if("object"!==t){nt(e,"data",r);break}case"src":case"href":if(""===r&&("a"!==t||"href"!==n)){e.removeAttribute(n);break}if(null==r||"function"==typeof r||"symbol"==typeof r||"boolean"==typeof r){e.removeAttribute(n);break}r=Lt(""+r),e.setAttribute(n,r);break;case"action":case"formAction":if("function"==typeof r){e.setAttribute(n,"javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')");break}if("function"==typeof o&&("formAction"===n?("input"!==t&&Zc(e,t,"name",a.name,a,null),Zc(e,t,"formEncType",a.formEncType,a,null),Zc(e,t,"formMethod",a.formMethod,a,null),Zc(e,t,"formTarget",a.formTarget,a,null)):(Zc(e,t,"encType",a.encType,a,null),Zc(e,t,"method",a.method,a,null),Zc(e,t,"target",a.target,a,null))),null==r||"symbol"==typeof r||"boolean"==typeof r){e.removeAttribute(n);break}r=Lt(""+r),e.setAttribute(n,r);break;case"onClick":null!=r&&(e.onclick=Xc);break;case"onScroll":null!=r&&Fc("scroll",e);break;case"onScrollEnd":null!=r&&Fc("scrollend",e);break;case"dangerouslySetInnerHTML":if(null!=r){if("object"!=typeof r||!("__html"in r))throw Error(i(61));if(null!=(n=r.__html)){if(null!=a.children)throw Error(i(60));e.innerHTML=n}}break;case"multiple":e.multiple=r&&"function"!=typeof r&&"symbol"!=typeof r;break;case"muted":e.muted=r&&"function"!=typeof r&&"symbol"!=typeof r;break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"defaultValue":case"defaultChecked":case"innerHTML":case"ref":case"autoFocus":break;case"xlinkHref":if(null==r||"function"==typeof r||"boolean"==typeof r||"symbol"==typeof r){e.removeAttribute("xlink:href");break}n=Lt(""+r),e.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",n);break;case"contentEditable":case"spellCheck":case"draggable":case"value":case"autoReverse":case"externalResourcesRequired":case"focusable":case"preserveAlpha":null!=r&&"function"!=typeof r&&"symbol"!=typeof r?e.setAttribute(n,""+r):e.removeAttribute(n);break;case"inert":case"allowFullScreen":case"async":case"autoPlay":case"controls":case"default":case"defer":case"disabled":case"disablePictureInPicture":case"disableRemotePlayback":case"formNoValidate":case"hidden":case"loop":case"noModule":case"noValidate":case"open":case"playsInline":case"readOnly":case"required":case"reversed":case"scoped":case"seamless":case"itemScope":r&&"function"!=typeof r&&"symbol"!=typeof r?e.setAttribute(n,""):e.removeAttribute(n);break;case"capture":case"download":!0===r?e.setAttribute(n,""):!1!==r&&null!=r&&"function"!=typeof r&&"symbol"!=typeof r?e.setAttribute(n,r):e.removeAttribute(n);break;case"cols":case"rows":case"size":case"span":null!=r&&"function"!=typeof r&&"symbol"!=typeof r&&!isNaN(r)&&1<=r?e.setAttribute(n,r):e.removeAttribute(n);break;case"rowSpan":case"start":null==r||"function"==typeof r||"symbol"==typeof r||isNaN(r)?e.removeAttribute(n):e.setAttribute(n,r);break;case"popover":Fc("beforetoggle",e),Fc("toggle",e),tt(e,"popover",r);break;case"xlinkActuate":rt(e,"http://www.w3.org/1999/xlink","xlink:actuate",r);break;case"xlinkArcrole":rt(e,"http://www.w3.org/1999/xlink","xlink:arcrole",r);break;case"xlinkRole":rt(e,"http://www.w3.org/1999/xlink","xlink:role",r);break;case"xlinkShow":rt(e,"http://www.w3.org/1999/xlink","xlink:show",r);break;case"xlinkTitle":rt(e,"http://www.w3.org/1999/xlink","xlink:title",r);break;case"xlinkType":rt(e,"http://www.w3.org/1999/xlink","xlink:type",r);break;case"xmlBase":rt(e,"http://www.w3.org/XML/1998/namespace","xml:base",r);break;case"xmlLang":rt(e,"http://www.w3.org/XML/1998/namespace","xml:lang",r);break;case"xmlSpace":rt(e,"http://www.w3.org/XML/1998/namespace","xml:space",r);break;case"is":tt(e,"is",r);break;case"innerText":case"textContent":break;default:(!(2<n.length)||"o"!==n[0]&&"O"!==n[0]||"n"!==n[1]&&"N"!==n[1])&&tt(e,n=At.get(n)||n,r)}}function Jc(e,t,n,r,a,o){switch(n){case"style":Et(e,r,o);break;case"dangerouslySetInnerHTML":if(null!=r){if("object"!=typeof r||!("__html"in r))throw Error(i(61));if(null!=(n=r.__html)){if(null!=a.children)throw Error(i(60));e.innerHTML=n}}break;case"children":"string"==typeof r?St(e,r):("number"==typeof r||"bigint"==typeof r)&&St(e,""+r);break;case"onScroll":null!=r&&Fc("scroll",e);break;case"onScrollEnd":null!=r&&Fc("scrollend",e);break;case"onClick":null!=r&&(e.onclick=Xc);break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"innerHTML":case"ref":case"innerText":case"textContent":break;default:We.hasOwnProperty(n)||("o"!==n[0]||"n"!==n[1]||(a=n.endsWith("Capture"),t=n.slice(2,a?n.length-7:void 0),"function"==typeof(o=null!=(o=e[Oe]||null)?o[n]:null)&&e.removeEventListener(t,o,a),"function"!=typeof r)?n in e?e[n]=r:!0===r?e.setAttribute(n,""):tt(e,n,r):("function"!=typeof o&&null!==o&&(n in e?e[n]=null:e.hasAttribute(n)&&e.removeAttribute(n)),e.addEventListener(t,r,a)))}}function ed(e,t,n){switch(t){case"div":case"span":case"svg":case"path":case"a":case"g":case"p":case"li":break;case"img":Fc("error",e),Fc("load",e);var r,a=!1,o=!1;for(r in n)if(n.hasOwnProperty(r)){var l=n[r];if(null!=l)switch(r){case"src":a=!0;break;case"srcSet":o=!0;break;case"children":case"dangerouslySetInnerHTML":throw Error(i(137,t));default:Zc(e,t,r,l,n,null)}}return o&&Zc(e,t,"srcSet",n.srcSet,n,null),void(a&&Zc(e,t,"src",n.src,n,null));case"input":Fc("invalid",e);var s=r=l=o=null,u=null,c=null;for(a in n)if(n.hasOwnProperty(a)){var d=n[a];if(null!=d)switch(a){case"name":o=d;break;case"type":l=d;break;case"checked":u=d;break;case"defaultChecked":c=d;break;case"value":r=d;break;case"defaultValue":s=d;break;case"children":case"dangerouslySetInnerHTML":if(null!=d)throw Error(i(137,t));break;default:Zc(e,t,a,d,n,null)}}return yt(e,r,s,u,c,l,o,!1),void dt(e);case"select":for(o in Fc("invalid",e),a=l=r=null,n)if(n.hasOwnProperty(o)&&null!=(s=n[o]))switch(o){case"value":r=s;break;case"defaultValue":l=s;break;case"multiple":a=s;default:Zc(e,t,o,s,n,null)}return t=r,n=l,e.multiple=!!a,void(null!=t?vt(e,!!a,t,!1):null!=n&&vt(e,!!a,n,!0));case"textarea":for(l in Fc("invalid",e),r=o=a=null,n)if(n.hasOwnProperty(l)&&null!=(s=n[l]))switch(l){case"value":a=s;break;case"defaultValue":o=s;break;case"children":r=s;break;case"dangerouslySetInnerHTML":if(null!=s)throw Error(i(91));break;default:Zc(e,t,l,s,n,null)}return kt(e,a,o,r),void dt(e);case"option":for(u in n)if(n.hasOwnProperty(u)&&null!=(a=n[u]))if("selected"===u)e.selected=a&&"function"!=typeof a&&"symbol"!=typeof a;else Zc(e,t,u,a,n,null);return;case"dialog":Fc("beforetoggle",e),Fc("toggle",e),Fc("cancel",e),Fc("close",e);break;case"iframe":case"object":Fc("load",e);break;case"video":case"audio":for(a=0;a<Rc.length;a++)Fc(Rc[a],e);break;case"image":Fc("error",e),Fc("load",e);break;case"details":Fc("toggle",e);break;case"embed":case"source":case"link":Fc("error",e),Fc("load",e);case"area":case"base":case"br":case"col":case"hr":case"keygen":case"meta":case"param":case"track":case"wbr":case"menuitem":for(c in n)if(n.hasOwnProperty(c)&&null!=(a=n[c]))switch(c){case"children":case"dangerouslySetInnerHTML":throw Error(i(137,t));default:Zc(e,t,c,a,n,null)}return;default:if(Ct(t)){for(d in n)n.hasOwnProperty(d)&&(void 0!==(a=n[d])&&Jc(e,t,d,a,n,void 0));return}}for(s in n)n.hasOwnProperty(s)&&(null!=(a=n[s])&&Zc(e,t,s,a,n,null))}var td=null,nd=null;function rd(e){return 9===e.nodeType?e:e.ownerDocument}function ad(e){switch(e){case"http://www.w3.org/2000/svg":return 1;case"http://www.w3.org/1998/Math/MathML":return 2;default:return 0}}function od(e,t){if(0===e)switch(t){case"svg":return 1;case"math":return 2;default:return 0}return 1===e&&"foreignObject"===t?0:e}function id(e,t){return"textarea"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"bigint"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var ld=null;var sd="function"==typeof setTimeout?setTimeout:void 0,ud="function"==typeof clearTimeout?clearTimeout:void 0,cd="function"==typeof Promise?Promise:void 0,dd="function"==typeof queueMicrotask?queueMicrotask:void 0!==cd?function(e){return cd.resolve(null).then(e).catch(fd)}:sd;function fd(e){setTimeout((function(){throw e}))}function pd(e){return"head"===e}function md(e,t){var n=t,r=0,a=0;do{var o=n.nextSibling;if(e.removeChild(n),o&&8===o.nodeType)if("/$"===(n=o.data)){if(0<r&&8>r){n=r;var i=e.ownerDocument;if(1&n&&kd(i.documentElement),2&n&&kd(i.body),4&n)for(kd(n=i.head),i=n.firstChild;i;){var l=i.nextSibling,s=i.nodeName;i[Be]||"SCRIPT"===s||"STYLE"===s||"LINK"===s&&"stylesheet"===i.rel.toLowerCase()||n.removeChild(i),i=l}}if(0===a)return e.removeChild(o),void Tf(t);a--}else"$"===n||"$?"===n||"$!"===n?a++:r=n.charCodeAt(0)-48;else r=0;n=o}while(n);Tf(t)}function hd(e){var t=e.firstChild;for(t&&10===t.nodeType&&(t=t.nextSibling);t;){var n=t;switch(t=t.nextSibling,n.nodeName){case"HTML":case"HEAD":case"BODY":hd(n),ze(n);continue;case"SCRIPT":case"STYLE":continue;case"LINK":if("stylesheet"===n.rel.toLowerCase())continue}e.removeChild(n)}}function gd(e){return"$!"===e.data||"$?"===e.data&&"complete"===e.ownerDocument.readyState}function yd(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break;if(8===t){if("$"===(t=e.data)||"$!"===t||"$?"===t||"F!"===t||"F"===t)break;if("/$"===t)return null}}return e}var bd=null;function vd(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}function wd(e,t,n){switch(t=rd(n),e){case"html":if(!(e=t.documentElement))throw Error(i(452));return e;case"head":if(!(e=t.head))throw Error(i(453));return e;case"body":if(!(e=t.body))throw Error(i(454));return e;default:throw Error(i(451))}}function kd(e){for(var t=e.attributes;t.length;)e.removeAttributeNode(t[0]);ze(e)}var Sd=new Map,xd=new Set;function _d(e){return"function"==typeof e.getRootNode?e.getRootNode():9===e.nodeType?e:e.ownerDocument}var Ed=M.d;M.d={f:function(){var e=Ed.f(),t=$u();return e||t},r:function(e){var t=Ue(e);null!==t&&5===t.tag&&"form"===t.type?Oi(t):Ed.r(e)},D:function(e){Ed.D(e),Ad("dns-prefetch",e,null)},C:function(e,t){Ed.C(e,t),Ad("preconnect",e,t)},L:function(e,t,n){Ed.L(e,t,n);var r=Cd;if(r&&e&&t){var a='link[rel="preload"][as="'+ht(t)+'"]';"image"===t&&n&&n.imageSrcSet?(a+='[imagesrcset="'+ht(n.imageSrcSet)+'"]',"string"==typeof n.imageSizes&&(a+='[imagesizes="'+ht(n.imageSizes)+'"]')):a+='[href="'+ht(e)+'"]';var o=a;switch(t){case"style":o=Ld(e);break;case"script":o=Nd(e)}Sd.has(o)||(e=f({rel:"preload",href:"image"===t&&n&&n.imageSrcSet?void 0:e,as:t},n),Sd.set(o,e),null!==r.querySelector(a)||"style"===t&&r.querySelector(jd(o))||"script"===t&&r.querySelector(Od(o))||(ed(t=r.createElement("link"),"link",e),Ge(t),r.head.appendChild(t)))}},m:function(e,t){Ed.m(e,t);var n=Cd;if(n&&e){var r=t&&"string"==typeof t.as?t.as:"script",a='link[rel="modulepreload"][as="'+ht(r)+'"][href="'+ht(e)+'"]',o=a;switch(r){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":o=Nd(e)}if(!Sd.has(o)&&(e=f({rel:"modulepreload",href:e},t),Sd.set(o,e),null===n.querySelector(a))){switch(r){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(n.querySelector(Od(o)))return}ed(r=n.createElement("link"),"link",e),Ge(r),n.head.appendChild(r)}}},X:function(e,t){Ed.X(e,t);var n=Cd;if(n&&e){var r=He(n).hoistableScripts,a=Nd(e),o=r.get(a);o||((o=n.querySelector(Od(a)))||(e=f({src:e,async:!0},t),(t=Sd.get(a))&&Fd(e,t),Ge(o=n.createElement("script")),ed(o,"link",e),n.head.appendChild(o)),o={type:"script",instance:o,count:1,state:null},r.set(a,o))}},S:function(e,t,n){Ed.S(e,t,n);var r=Cd;if(r&&e){var a=He(r).hoistableStyles,o=Ld(e);t=t||"default";var i=a.get(o);if(!i){var l={loading:0,preload:null};if(i=r.querySelector(jd(o)))l.loading=5;else{e=f({rel:"stylesheet",href:e,"data-precedence":t},n),(n=Sd.get(o))&&Dd(e,n);var s=i=r.createElement("link");Ge(s),ed(s,"link",e),s._p=new Promise((function(e,t){s.onload=e,s.onerror=t})),s.addEventListener("load",(function(){l.loading|=1})),s.addEventListener("error",(function(){l.loading|=2})),l.loading|=4,Md(i,t,r)}i={type:"stylesheet",instance:i,count:1,state:l},a.set(o,i)}}},M:function(e,t){Ed.M(e,t);var n=Cd;if(n&&e){var r=He(n).hoistableScripts,a=Nd(e),o=r.get(a);o||((o=n.querySelector(Od(a)))||(e=f({src:e,async:!0,type:"module"},t),(t=Sd.get(a))&&Fd(e,t),Ge(o=n.createElement("script")),ed(o,"link",e),n.head.appendChild(o)),o={type:"script",instance:o,count:1,state:null},r.set(a,o))}}};var Cd="undefined"==typeof document?null:document;function Ad(e,t,n){var r=Cd;if(r&&"string"==typeof t&&t){var a=ht(t);a='link[rel="'+e+'"][href="'+a+'"]',"string"==typeof n&&(a+='[crossorigin="'+n+'"]'),xd.has(a)||(xd.add(a),e={rel:e,crossOrigin:n,href:t},null===r.querySelector(a)&&(ed(t=r.createElement("link"),"link",e),Ge(t),r.head.appendChild(t)))}}function Td(e,t,n,r){var a,o,l,s,u=(u=H.current)?_d(u):null;if(!u)throw Error(i(446));switch(e){case"meta":case"title":return null;case"style":return"string"==typeof n.precedence&&"string"==typeof n.href?(t=Ld(n.href),(r=(n=He(u).hoistableStyles).get(t))||(r={type:"style",instance:null,count:0,state:null},n.set(t,r)),r):{type:"void",instance:null,count:0,state:null};case"link":if("stylesheet"===n.rel&&"string"==typeof n.href&&"string"==typeof n.precedence){e=Ld(n.href);var c=He(u).hoistableStyles,d=c.get(e);if(d||(u=u.ownerDocument||u,d={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},c.set(e,d),(c=u.querySelector(jd(e)))&&!c._p&&(d.instance=c,d.state.loading=5),Sd.has(e)||(n={rel:"preload",as:"style",href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},Sd.set(e,n),c||(a=u,o=e,l=n,s=d.state,a.querySelector('link[rel="preload"][as="style"]['+o+"]")?s.loading=1:(o=a.createElement("link"),s.preload=o,o.addEventListener("load",(function(){return s.loading|=1})),o.addEventListener("error",(function(){return s.loading|=2})),ed(o,"link",l),Ge(o),a.head.appendChild(o))))),t&&null===r)throw Error(i(528,""));return d}if(t&&null!==r)throw Error(i(529,""));return null;case"script":return t=n.async,"string"==typeof(n=n.src)&&t&&"function"!=typeof t&&"symbol"!=typeof t?(t=Nd(n),(r=(n=He(u).hoistableScripts).get(t))||(r={type:"script",instance:null,count:0,state:null},n.set(t,r)),r):{type:"void",instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Ld(e){return'href="'+ht(e)+'"'}function jd(e){return'link[rel="stylesheet"]['+e+"]"}function Pd(e){return f({},e,{"data-precedence":e.precedence,precedence:null})}function Nd(e){return'[src="'+ht(e)+'"]'}function Od(e){return"script[async]"+e}function Rd(e,t,n){if(t.count++,null===t.instance)switch(t.type){case"style":var r=e.querySelector('style[data-href~="'+ht(n.href)+'"]');if(r)return t.instance=r,Ge(r),r;var a=f({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return Ge(r=(e.ownerDocument||e).createElement("style")),ed(r,"style",a),Md(r,n.precedence,e),t.instance=r;case"stylesheet":a=Ld(n.href);var o=e.querySelector(jd(a));if(o)return t.state.loading|=4,t.instance=o,Ge(o),o;r=Pd(n),(a=Sd.get(a))&&Dd(r,a),Ge(o=(e.ownerDocument||e).createElement("link"));var l=o;return l._p=new Promise((function(e,t){l.onload=e,l.onerror=t})),ed(o,"link",r),t.state.loading|=4,Md(o,n.precedence,e),t.instance=o;case"script":return o=Nd(n.src),(a=e.querySelector(Od(o)))?(t.instance=a,Ge(a),a):(r=n,(a=Sd.get(o))&&Fd(r=f({},n),a),Ge(a=(e=e.ownerDocument||e).createElement("script")),ed(a,"link",r),e.head.appendChild(a),t.instance=a);case"void":return null;default:throw Error(i(443,t.type))}else"stylesheet"===t.type&&!(4&t.state.loading)&&(r=t.instance,t.state.loading|=4,Md(r,n.precedence,e));return t.instance}function Md(e,t,n){for(var r=n.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),a=r.length?r[r.length-1]:null,o=a,i=0;i<r.length;i++){var l=r[i];if(l.dataset.precedence===t)o=l;else if(o!==a)break}o?o.parentNode.insertBefore(e,o.nextSibling):(t=9===n.nodeType?n.head:n).insertBefore(e,t.firstChild)}function Dd(e,t){null==e.crossOrigin&&(e.crossOrigin=t.crossOrigin),null==e.referrerPolicy&&(e.referrerPolicy=t.referrerPolicy),null==e.title&&(e.title=t.title)}function Fd(e,t){null==e.crossOrigin&&(e.crossOrigin=t.crossOrigin),null==e.referrerPolicy&&(e.referrerPolicy=t.referrerPolicy),null==e.integrity&&(e.integrity=t.integrity)}var Id=null;function Bd(e,t,n){if(null===Id){var r=new Map,a=Id=new Map;a.set(n,r)}else(r=(a=Id).get(n))||(r=new Map,a.set(n,r));if(r.has(e))return r;for(r.set(e,null),n=n.getElementsByTagName(e),a=0;a<n.length;a++){var o=n[a];if(!(o[Be]||o[Ne]||"link"===e&&"stylesheet"===o.getAttribute("rel"))&&"http://www.w3.org/2000/svg"!==o.namespaceURI){var i=o.getAttribute(t)||"";i=e+i;var l=r.get(i);l?l.push(o):r.set(i,[o])}}return r}function zd(e,t,n){(e=e.ownerDocument||e).head.insertBefore(n,"title"===t?e.querySelector("head > title"):null)}function $d(e){return!!("stylesheet"!==e.type||3&e.state.loading)}var Ud=null;function qd(){}function Hd(){if(this.count--,0===this.count)if(this.stylesheets)Vd(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}var Gd=null;function Vd(e,t){e.stylesheets=null,null!==e.unsuspend&&(e.count++,Gd=new Map,t.forEach(Wd,e),Gd=null,Hd.call(e))}function Wd(e,t){if(!(4&t.state.loading)){var n=Gd.get(e);if(n)var r=n.get(null);else{n=new Map,Gd.set(e,n);for(var a=e.querySelectorAll("link[data-precedence],style[data-precedence]"),o=0;o<a.length;o++){var i=a[o];"LINK"!==i.nodeName&&"not all"===i.getAttribute("media")||(n.set(i.dataset.precedence,i),r=i)}r&&n.set(null,r)}i=(a=t.instance).getAttribute("data-precedence"),(o=n.get(i)||r)===r&&n.set(null,a),n.set(i,a),this.count++,r=Hd.bind(this),a.addEventListener("load",r),a.addEventListener("error",r),o?o.parentNode.insertBefore(a,o.nextSibling):(e=9===e.nodeType?e.head:e).insertBefore(a,e.firstChild),t.state.loading|=4}}var Qd={$$typeof:k,Provider:null,Consumer:null,_currentValue:D,_currentValue2:D,_threadCount:0};function Kd(e,t,n,r,a,o,i,l){this.tag=1,this.containerInfo=e,this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.next=this.pendingContext=this.context=this.cancelPendingCommit=null,this.callbackPriority=0,this.expirationTimes=_e(-1),this.entangledLanes=this.shellSuspendCounter=this.errorRecoveryDisabledLanes=this.expiredLanes=this.warmLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=_e(0),this.hiddenUpdates=_e(null),this.identifierPrefix=r,this.onUncaughtError=a,this.onCaughtError=o,this.onRecoverableError=i,this.pooledCache=null,this.pooledCacheLanes=0,this.formState=l,this.incompleteTransitions=new Map}function Yd(e,t,n,r,a,o,i,l,s,u,c,d){return e=new Kd(e,t,n,i,l,s,u,d),t=1,!0===o&&(t|=24),o=Dr(3,null,null,t),e.current=o,o.stateNode=e,(t=Oa()).refCount++,e.pooledCache=t,t.refCount++,o.memoizedState={element:r,isDehydrated:n,cache:t},no(o),e}function Xd(e){return e?e=Rr:Rr}function Zd(e,t,n,r,a,o){a=Xd(a),null===r.context?r.context=a:r.pendingContext=a,(r=ao(t)).payload={element:n},null!==(o=void 0===o?null:o)&&(r.callback=o),null!==(n=oo(e,r,t))&&(Du(n,0,t),io(n,e,t))}function Jd(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function ef(e,t){Jd(e,t),(e=e.alternate)&&Jd(e,t)}function tf(e){if(13===e.tag){var t=Pr(e,67108864);null!==t&&Du(t,0,67108864),ef(e,67108864)}}var nf=!0;function rf(e,t,n,r){var a=R.T;R.T=null;var o=M.p;try{M.p=2,of(e,t,n,r)}finally{M.p=o,R.T=a}}function af(e,t,n,r){var a=R.T;R.T=null;var o=M.p;try{M.p=8,of(e,t,n,r)}finally{M.p=o,R.T=a}}function of(e,t,n,r){if(nf){var a=lf(r);if(null===a)Uc(e,t,r,sf,n),vf(e,r);else if(function(e,t,n,r,a){switch(t){case"focusin":return ff=wf(ff,e,t,n,r,a),!0;case"dragenter":return pf=wf(pf,e,t,n,r,a),!0;case"mouseover":return mf=wf(mf,e,t,n,r,a),!0;case"pointerover":var o=a.pointerId;return hf.set(o,wf(hf.get(o)||null,e,t,n,r,a)),!0;case"gotpointercapture":return o=a.pointerId,gf.set(o,wf(gf.get(o)||null,e,t,n,r,a)),!0}return!1}(a,e,t,n,r))r.stopPropagation();else if(vf(e,r),4&t&&-1<bf.indexOf(e)){for(;null!==a;){var o=Ue(a);if(null!==o)switch(o.tag){case 3:if((o=o.stateNode).current.memoizedState.isDehydrated){var i=be(o.pendingLanes);if(0!==i){var l=o;for(l.pendingLanes|=2,l.entangledLanes|=2;i;){var s=1<<31-pe(i);l.entanglements[1]|=s,i&=~s}Sc(o),!(6&nu)&&(Su=te()+500,xc(0,!1))}}break;case 13:null!==(l=Pr(o,2))&&Du(l,0,2),$u(),ef(o,2)}if(null===(o=lf(r))&&Uc(e,t,r,sf,n),o===a)break;a=o}null!==a&&r.stopPropagation()}else Uc(e,t,r,null,n)}}function lf(e){return uf(e=Pt(e))}var sf=null;function uf(e){if(sf=null,null!==(e=$e(e))){var t=s(e);if(null===t)e=null;else{var n=t.tag;if(13===n){if(null!==(e=u(t)))return e;e=null}else if(3===n){if(t.stateNode.current.memoizedState.isDehydrated)return 3===t.tag?t.stateNode.containerInfo:null;e=null}else t!==e&&(e=null)}}return sf=e,null}function cf(e){switch(e){case"beforetoggle":case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"toggle":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 2;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 8;case"message":switch(ne()){case re:return 2;case ae:return 8;case oe:case ie:return 32;case le:return 268435456;default:return 32}default:return 32}}var df=!1,ff=null,pf=null,mf=null,hf=new Map,gf=new Map,yf=[],bf="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset".split(" ");function vf(e,t){switch(e){case"focusin":case"focusout":ff=null;break;case"dragenter":case"dragleave":pf=null;break;case"mouseover":case"mouseout":mf=null;break;case"pointerover":case"pointerout":hf.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":gf.delete(t.pointerId)}}function wf(e,t,n,r,a,o){return null===e||e.nativeEvent!==o?(e={blockedOn:t,domEventName:n,eventSystemFlags:r,nativeEvent:o,targetContainers:[a]},null!==t&&(null!==(t=Ue(t))&&tf(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,null!==a&&-1===t.indexOf(a)&&t.push(a),e)}function kf(e){var t=$e(e.target);if(null!==t){var n=s(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=u(n)))return e.blockedOn=t,void function(e,t){var n=M.p;try{return M.p=e,t()}finally{M.p=n}}(e.priority,(function(){if(13===n.tag){var e=Ru();e=Te(e);var t=Pr(n,e);null!==t&&Du(t,0,e),ef(n,e)}}))}else if(3===t&&n.stateNode.current.memoizedState.isDehydrated)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function Sf(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=lf(e.nativeEvent);if(null!==n)return null!==(t=Ue(n))&&tf(t),e.blockedOn=n,!1;var r=new(n=e.nativeEvent).constructor(n.type,n);jt=r,n.target.dispatchEvent(r),jt=null,t.shift()}return!0}function xf(e,t,n){Sf(e)&&n.delete(t)}function _f(){df=!1,null!==ff&&Sf(ff)&&(ff=null),null!==pf&&Sf(pf)&&(pf=null),null!==mf&&Sf(mf)&&(mf=null),hf.forEach(xf),gf.forEach(xf)}function Ef(e,t){e.blockedOn===t&&(e.blockedOn=null,df||(df=!0,r.unstable_scheduleCallback(r.unstable_NormalPriority,_f)))}var Cf=null;function Af(e){Cf!==e&&(Cf=e,r.unstable_scheduleCallback(r.unstable_NormalPriority,(function(){Cf===e&&(Cf=null);for(var t=0;t<e.length;t+=3){var n=e[t],r=e[t+1],a=e[t+2];if("function"!=typeof r){if(null===uf(r||n))continue;break}var o=Ue(n);null!==o&&(e.splice(t,3),t-=3,Pi(o,{pending:!0,data:a,method:n.method,action:r},r,a))}})))}function Tf(e){function t(t){return Ef(t,e)}null!==ff&&Ef(ff,e),null!==pf&&Ef(pf,e),null!==mf&&Ef(mf,e),hf.forEach(t),gf.forEach(t);for(var n=0;n<yf.length;n++){var r=yf[n];r.blockedOn===e&&(r.blockedOn=null)}for(;0<yf.length&&null===(n=yf[0]).blockedOn;)kf(n),null===n.blockedOn&&yf.shift();if(null!=(n=(e.ownerDocument||e).$$reactFormReplay))for(r=0;r<n.length;r+=3){var a=n[r],o=n[r+1],i=a[Oe]||null;if("function"==typeof o)i||Af(n);else if(i){var l=null;if(o&&o.hasAttribute("formAction")){if(a=o,i=o[Oe]||null)l=i.formAction;else if(null!==uf(a))continue}else l=i.action;"function"==typeof l?n[r+1]=l:(n.splice(r,3),r-=3),Af(n)}}}function Lf(e){this._internalRoot=e}function jf(e){this._internalRoot=e}jf.prototype.render=Lf.prototype.render=function(e){var t=this._internalRoot;if(null===t)throw Error(i(409));Zd(t.current,Ru(),e,t,null,null)},jf.prototype.unmount=Lf.prototype.unmount=function(){var e=this._internalRoot;if(null!==e){this._internalRoot=null;var t=e.containerInfo;Zd(e.current,2,null,e,null,null),$u(),t[Re]=null}},jf.prototype.unstable_scheduleHydration=function(e){if(e){var t=je();e={blockedOn:null,target:e,priority:t};for(var n=0;n<yf.length&&0!==t&&t<yf[n].priority;n++);yf.splice(n,0,e),0===n&&kf(e)}};var Pf=a.version;if("19.1.0"!==Pf)throw Error(i(527,Pf,"19.1.0"));M.findDOMNode=function(e){var t=e._reactInternals;if(void 0===t){if("function"==typeof e.render)throw Error(i(188));throw e=Object.keys(e).join(","),Error(i(268,e))}return e=function(e){var t=e.alternate;if(!t){if(null===(t=s(e)))throw Error(i(188));return t!==e?null:e}for(var n=e,r=t;;){var a=n.return;if(null===a)break;var o=a.alternate;if(null===o){if(null!==(r=a.return)){n=r;continue}break}if(a.child===o.child){for(o=a.child;o;){if(o===n)return c(a),e;if(o===r)return c(a),t;o=o.sibling}throw Error(i(188))}if(n.return!==r.return)n=a,r=o;else{for(var l=!1,u=a.child;u;){if(u===n){l=!0,n=a,r=o;break}if(u===r){l=!0,r=a,n=o;break}u=u.sibling}if(!l){for(u=o.child;u;){if(u===n){l=!0,n=o,r=a;break}if(u===r){l=!0,r=o,n=a;break}u=u.sibling}if(!l)throw Error(i(189))}}if(n.alternate!==r)throw Error(i(190))}if(3!==n.tag)throw Error(i(188));return n.stateNode.current===n?e:t}(t),e=null===(e=null!==e?d(e):null)?null:e.stateNode};var Nf={bundleType:0,version:"19.1.0",rendererPackageName:"react-dom",currentDispatcherRef:R,reconcilerVersion:"19.1.0"};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var Of=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!Of.isDisabled&&Of.supportsFiber)try{ce=Of.inject(Nf),de=Of}catch(Mf){}}t.createRoot=function(e,t){if(!l(e))throw Error(i(299));var n=!1,r="",a=bl,o=vl,s=wl;return null!=t&&(!0===t.unstable_strictMode&&(n=!0),void 0!==t.identifierPrefix&&(r=t.identifierPrefix),void 0!==t.onUncaughtError&&(a=t.onUncaughtError),void 0!==t.onCaughtError&&(o=t.onCaughtError),void 0!==t.onRecoverableError&&(s=t.onRecoverableError),void 0!==t.unstable_transitionCallbacks&&t.unstable_transitionCallbacks),t=Yd(e,1,!1,null,0,n,r,a,o,s,0,null),e[Re]=t.current,zc(e),new Lf(t)},t.hydrateRoot=function(e,t,n){if(!l(e))throw Error(i(299));var r=!1,a="",o=bl,s=vl,u=wl,c=null;return null!=n&&(!0===n.unstable_strictMode&&(r=!0),void 0!==n.identifierPrefix&&(a=n.identifierPrefix),void 0!==n.onUncaughtError&&(o=n.onUncaughtError),void 0!==n.onCaughtError&&(s=n.onCaughtError),void 0!==n.onRecoverableError&&(u=n.onRecoverableError),void 0!==n.unstable_transitionCallbacks&&n.unstable_transitionCallbacks,void 0!==n.formState&&(c=n.formState)),(t=Yd(e,1,!0,t,0,r,a,o,s,u,0,c)).context=Xd(null),n=t.current,(a=ao(r=Te(r=Ru()))).callback=null,oo(n,a,r),n=r,t.current.lanes=n,Ee(t,n),Sc(t),e[Re]=t.current,zc(e),new jf(t)},t.version="19.1.0"},1312:(e,t,n)=>{"use strict";n.d(t,{A:()=>u,T:()=>s});var r=n(6540),a=n(4848);function o(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(2654);function l({id:e,message:t}){if(void 0===e&&void 0===t)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[e??t]??t??e}function s({message:e,id:t},n){return o(l({message:e,id:t}),n)}function u({children:e,id:t,values:n}){if(e&&"string"!=typeof e)throw console.warn("Illegal <Translate> children",e),new Error("The Docusaurus <Translate> component only accept simple string values");const r=l({message:e,id:t});return(0,a.jsx)(a.Fragment,{children:o(r,n)})}},1422:(e,t,n)=>{"use strict";n.d(t,{N:()=>h,u:()=>s});var r=n(6540),a=n(205),o=n(3109),i=n(4848);const l="ease-in-out";function s({initialState:e}){const[t,n]=(0,r.useState)(e??!1),a=(0,r.useCallback)((()=>{n((e=>!e))}),[]);return{collapsed:t,setCollapsed:n,toggleCollapsed:a}}const u={display:"none",overflow:"hidden",height:"0px"},c={display:"block",overflow:"visible",height:"auto"};function d(e,t){const n=t?u:c;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f({collapsibleRef:e,collapsed:t,animation:n}){const a=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const r=e.current;function i(){const e=r.scrollHeight,t=n?.duration??function(e){if((0,o.O)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(e);return{transition:`height ${t}ms ${n?.easing??l}`,height:`${e}px`}}function s(){const e=i();r.style.transition=e.transition,r.style.height=e.height}if(!a.current)return d(r,t),void(a.current=!0);return r.style.willChange="height",function(){const e=requestAnimationFrame((()=>{t?(s(),requestAnimationFrame((()=>{r.style.height=u.height,r.style.overflow=u.overflow}))):(r.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(e)}()}),[e,t,n])}function p({as:e="div",collapsed:t,children:n,animation:a,onCollapseTransitionEnd:o,className:l}){const s=(0,r.useRef)(null);return f({collapsibleRef:s,collapsed:t,animation:a}),(0,i.jsx)(e,{ref:s,onTransitionEnd:e=>{"height"===e.propertyName&&(d(s.current,t),o?.(t))},className:l,children:n})}function m({collapsed:e,...t}){const[n,o]=(0,r.useState)(!e),[l,s]=(0,r.useState)(e);return(0,a.A)((()=>{e||o(!0)}),[e]),(0,a.A)((()=>{n&&s(e)}),[n,e]),n?(0,i.jsx)(p,{...t,collapsed:l}):null}function h({lazy:e,...t}){const n=e?m:p;return(0,i.jsx)(n,{...t})}},1463:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});n(6540);var r=n(5260),a=n(4848);function o({locale:e,version:t,tag:n}){const o=e;return(0,a.jsxs)(r.A,{children:[e&&(0,a.jsx)("meta",{name:"docusaurus_locale",content:e}),t&&(0,a.jsx)("meta",{name:"docusaurus_version",content:t}),n&&(0,a.jsx)("meta",{name:"docusaurus_tag",content:n}),o&&(0,a.jsx)("meta",{name:"docsearch:language",content:o}),t&&(0,a.jsx)("meta",{name:"docsearch:version",content:t}),n&&(0,a.jsx)("meta",{name:"docsearch:docusaurus_tag",content:n})]})}},1513:(e,t,n)=>{"use strict";n.d(t,{zR:()=>w,TM:()=>C,yJ:()=>p,sC:()=>T,AO:()=>f});var r=n(8168);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r<a;n+=1,r+=1)e[n]=e[r];e.pop()}const i=function(e,t){void 0===t&&(t="");var n,r=e&&e.split("/")||[],i=t&&t.split("/")||[],l=e&&a(e),s=t&&a(t),u=l||s;if(e&&a(e)?i=r:r.length&&(i.pop(),i=i.concat(r)),!i.length)return"/";if(i.length){var c=i[i.length-1];n="."===c||".."===c||""===c}else n=!1;for(var d=0,f=i.length;f>=0;f--){var p=i[f];"."===p?o(i,f):".."===p?(o(i,f),d++):d&&(o(i,f),d--)}if(!u)for(;d--;d)i.unshift("..");!u||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var l=n(1561);function s(e){return"/"===e.charAt(0)?e:"/"+e}function u(e){return"/"===e.charAt(0)?e.substr(1):e}function c(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function f(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function p(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.A)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];t.forEach((function(e){return e.apply(void 0,n)}))}}}var h=!("undefined"==typeof window||!window.document||!window.document.createElement);function g(e,t){t(window.confirm(e))}var y="popstate",b="hashchange";function v(){try{return window.history.state||{}}catch(e){return{}}}function w(e){void 0===e&&(e={}),h||(0,l.A)(!1);var t,n=window.history,a=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,o=!(-1===window.navigator.userAgent.indexOf("Trident")),i=e,u=i.forceRefresh,w=void 0!==u&&u,k=i.getUserConfirmation,S=void 0===k?g:k,x=i.keyLength,_=void 0===x?6:x,E=e.basename?d(s(e.basename)):"";function C(e){var t=e||{},n=t.key,r=t.state,a=window.location,o=a.pathname+a.search+a.hash;return E&&(o=c(o,E)),p(o,r,n)}function A(){return Math.random().toString(36).substr(2,_)}var T=m();function L(e){(0,r.A)($,e),$.length=n.length,T.notifyListeners($.location,$.action)}function j(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||O(C(e.state))}function P(){O(C(v()))}var N=!1;function O(e){if(N)N=!1,L();else{T.confirmTransitionTo(e,"POP",S,(function(t){t?L({action:"POP",location:e}):function(e){var t=$.location,n=M.indexOf(t.key);-1===n&&(n=0);var r=M.indexOf(e.key);-1===r&&(r=0);var a=n-r;a&&(N=!0,F(a))}(e)}))}}var R=C(v()),M=[R.key];function D(e){return E+f(e)}function F(e){n.go(e)}var I=0;function B(e){1===(I+=e)&&1===e?(window.addEventListener(y,j),o&&window.addEventListener(b,P)):0===I&&(window.removeEventListener(y,j),o&&window.removeEventListener(b,P))}var z=!1;var $={length:n.length,action:"POP",location:R,createHref:D,push:function(e,t){var r="PUSH",o=p(e,t,A(),$.location);T.confirmTransitionTo(o,r,S,(function(e){if(e){var t=D(o),i=o.key,l=o.state;if(a)if(n.pushState({key:i,state:l},null,t),w)window.location.href=t;else{var s=M.indexOf($.location.key),u=M.slice(0,s+1);u.push(o.key),M=u,L({action:r,location:o})}else window.location.href=t}}))},replace:function(e,t){var r="REPLACE",o=p(e,t,A(),$.location);T.confirmTransitionTo(o,r,S,(function(e){if(e){var t=D(o),i=o.key,l=o.state;if(a)if(n.replaceState({key:i,state:l},null,t),w)window.location.replace(t);else{var s=M.indexOf($.location.key);-1!==s&&(M[s]=o.key),L({action:r,location:o})}else window.location.replace(t)}}))},go:F,goBack:function(){F(-1)},goForward:function(){F(1)},block:function(e){void 0===e&&(e=!1);var t=T.setPrompt(e);return z||(B(1),z=!0),function(){return z&&(z=!1,B(-1)),t()}},listen:function(e){var t=T.appendListener(e);return B(1),function(){B(-1),t()}}};return $}var k="hashchange",S={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+u(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:u,decodePath:s},slash:{encodePath:s,decodePath:s}};function x(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function _(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function E(e){window.location.replace(x(window.location.href)+"#"+e)}function C(e){void 0===e&&(e={}),h||(0,l.A)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),a=n.getUserConfirmation,o=void 0===a?g:a,i=n.hashType,u=void 0===i?"slash":i,y=e.basename?d(s(e.basename)):"",b=S[u],v=b.encodePath,w=b.decodePath;function C(){var e=w(_());return y&&(e=c(e,y)),p(e)}var A=m();function T(e){(0,r.A)(z,e),z.length=t.length,A.notifyListeners(z.location,z.action)}var L=!1,j=null;function P(){var e,t,n=_(),r=v(n);if(n!==r)E(r);else{var a=C(),i=z.location;if(!L&&(t=a,(e=i).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(j===f(a))return;j=null,function(e){if(L)L=!1,T();else{var t="POP";A.confirmTransitionTo(e,t,o,(function(n){n?T({action:t,location:e}):function(e){var t=z.location,n=M.lastIndexOf(f(t));-1===n&&(n=0);var r=M.lastIndexOf(f(e));-1===r&&(r=0);var a=n-r;a&&(L=!0,D(a))}(e)}))}}(a)}}var N=_(),O=v(N);N!==O&&E(O);var R=C(),M=[f(R)];function D(e){t.go(e)}var F=0;function I(e){1===(F+=e)&&1===e?window.addEventListener(k,P):0===F&&window.removeEventListener(k,P)}var B=!1;var z={length:t.length,action:"POP",location:R,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=x(window.location.href)),n+"#"+v(y+f(e))},push:function(e,t){var n="PUSH",r=p(e,void 0,void 0,z.location);A.confirmTransitionTo(r,n,o,(function(e){if(e){var t=f(r),a=v(y+t);if(_()!==a){j=t,function(e){window.location.hash=e}(a);var o=M.lastIndexOf(f(z.location)),i=M.slice(0,o+1);i.push(t),M=i,T({action:n,location:r})}else T()}}))},replace:function(e,t){var n="REPLACE",r=p(e,void 0,void 0,z.location);A.confirmTransitionTo(r,n,o,(function(e){if(e){var t=f(r),a=v(y+t);_()!==a&&(j=t,E(a));var o=M.indexOf(f(z.location));-1!==o&&(M[o]=t),T({action:n,location:r})}}))},go:D,goBack:function(){D(-1)},goForward:function(){D(1)},block:function(e){void 0===e&&(e=!1);var t=A.setPrompt(e);return B||(I(1),B=!0),function(){return B&&(B=!1,I(-1)),t()}},listen:function(e){var t=A.appendListener(e);return I(1),function(){I(-1),t()}}};return z}function A(e,t,n){return Math.min(Math.max(e,t),n)}function T(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,a=t.initialEntries,o=void 0===a?["/"]:a,i=t.initialIndex,l=void 0===i?0:i,s=t.keyLength,u=void 0===s?6:s,c=m();function d(e){(0,r.A)(w,e),w.length=w.entries.length,c.notifyListeners(w.location,w.action)}function h(){return Math.random().toString(36).substr(2,u)}var g=A(l,0,o.length-1),y=o.map((function(e){return p(e,void 0,"string"==typeof e?h():e.key||h())})),b=f;function v(e){var t=A(w.index+e,0,w.entries.length-1),r=w.entries[t];c.confirmTransitionTo(r,"POP",n,(function(e){e?d({action:"POP",location:r,index:t}):d()}))}var w={length:y.length,action:"POP",location:y[g],index:g,entries:y,createHref:b,push:function(e,t){var r="PUSH",a=p(e,t,h(),w.location);c.confirmTransitionTo(a,r,n,(function(e){if(e){var t=w.index+1,n=w.entries.slice(0);n.length>t?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=p(e,t,h(),w.location);c.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=w.index+e;return t>=0&&t<w.entries.length},block:function(e){return void 0===e&&(e=!1),c.setPrompt(e)},listen:function(e){return c.appendListener(e)}};return w}},1561:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=!0,a="Invariant failed";function o(e,t){if(!e){if(r)throw new Error(a);var n="function"==typeof t?t():t,o=n?"".concat(a,": ").concat(n):a;throw new Error(o)}}},1635:(e,t,n)=>{"use strict";n.r(t),n.d(t,{__addDisposableResource:()=>M,__assign:()=>o,__asyncDelegator:()=>E,__asyncGenerator:()=>_,__asyncValues:()=>C,__await:()=>x,__awaiter:()=>m,__classPrivateFieldGet:()=>N,__classPrivateFieldIn:()=>R,__classPrivateFieldSet:()=>O,__createBinding:()=>g,__decorate:()=>l,__disposeResources:()=>F,__esDecorate:()=>u,__exportStar:()=>y,__extends:()=>a,__generator:()=>h,__importDefault:()=>P,__importStar:()=>j,__makeTemplateObject:()=>A,__metadata:()=>p,__param:()=>s,__propKey:()=>d,__read:()=>v,__rest:()=>i,__rewriteRelativeImportExtension:()=>I,__runInitializers:()=>c,__setFunctionName:()=>f,__spread:()=>w,__spreadArray:()=>S,__spreadArrays:()=>k,__values:()=>b,default:()=>B});var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},r(e,t)};function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var o=function(){return o=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var a in t=arguments[n])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e},o.apply(this,arguments)};function i(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var a=0;for(r=Object.getOwnPropertySymbols(e);a<r.length;a++)t.indexOf(r[a])<0&&Object.prototype.propertyIsEnumerable.call(e,r[a])&&(n[r[a]]=e[r[a]])}return n}function l(e,t,n,r){var a,o=arguments.length,i=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,n,r);else for(var l=e.length-1;l>=0;l--)(a=e[l])&&(i=(o<3?a(i):o>3?a(t,n,i):a(t,n))||i);return o>3&&i&&Object.defineProperty(t,n,i),i}function s(e,t){return function(n,r){t(n,r,e)}}function u(e,t,n,r,a,o){function i(e){if(void 0!==e&&"function"!=typeof e)throw new TypeError("Function expected");return e}for(var l,s=r.kind,u="getter"===s?"get":"setter"===s?"set":"value",c=!t&&e?r.static?e:e.prototype:null,d=t||(c?Object.getOwnPropertyDescriptor(c,r.name):{}),f=!1,p=n.length-1;p>=0;p--){var m={};for(var h in r)m[h]="access"===h?{}:r[h];for(var h in r.access)m.access[h]=r.access[h];m.addInitializer=function(e){if(f)throw new TypeError("Cannot add initializers after decoration has completed");o.push(i(e||null))};var g=(0,n[p])("accessor"===s?{get:d.get,set:d.set}:d[u],m);if("accessor"===s){if(void 0===g)continue;if(null===g||"object"!=typeof g)throw new TypeError("Object expected");(l=i(g.get))&&(d.get=l),(l=i(g.set))&&(d.set=l),(l=i(g.init))&&a.unshift(l)}else(l=i(g))&&("field"===s?a.unshift(l):d[u]=l)}c&&Object.defineProperty(c,r.name,d),f=!0}function c(e,t,n){for(var r=arguments.length>2,a=0;a<t.length;a++)n=r?t[a].call(e,n):t[a].call(e);return r?n:void 0}function d(e){return"symbol"==typeof e?e:"".concat(e)}function f(e,t,n){return"symbol"==typeof t&&(t=t.description?"[".concat(t.description,"]"):""),Object.defineProperty(e,"name",{configurable:!0,value:n?"".concat(n," ",t):t})}function p(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function m(e,t,n,r){return new(n||(n=Promise))((function(a,o){function i(e){try{s(r.next(e))}catch(t){o(t)}}function l(e){try{s(r.throw(e))}catch(t){o(t)}}function s(e){var t;e.done?a(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,l)}s((r=r.apply(e,t||[])).next())}))}function h(e,t){var n,r,a,o={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return i.next=l(0),i.throw=l(1),i.return=l(2),"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function l(l){return function(s){return function(l){if(n)throw new TypeError("Generator is already executing.");for(;i&&(i=0,l[0]&&(o=0)),o;)try{if(n=1,r&&(a=2&l[0]?r.return:l[0]?r.throw||((a=r.return)&&a.call(r),0):r.next)&&!(a=a.call(r,l[1])).done)return a;switch(r=0,a&&(l=[2&l[0],a.value]),l[0]){case 0:case 1:a=l;break;case 4:return o.label++,{value:l[1],done:!1};case 5:o.label++,r=l[1],l=[0];continue;case 7:l=o.ops.pop(),o.trys.pop();continue;default:if(!(a=o.trys,(a=a.length>0&&a[a.length-1])||6!==l[0]&&2!==l[0])){o=0;continue}if(3===l[0]&&(!a||l[1]>a[0]&&l[1]<a[3])){o.label=l[1];break}if(6===l[0]&&o.label<a[1]){o.label=a[1],a=l;break}if(a&&o.label<a[2]){o.label=a[2],o.ops.push(l);break}a[2]&&o.ops.pop(),o.trys.pop();continue}l=t.call(e,o)}catch(s){l=[6,s],r=0}finally{n=a=0}if(5&l[0])throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}([l,s])}}}var g=Object.create?function(e,t,n,r){void 0===r&&(r=n);var a=Object.getOwnPropertyDescriptor(t,n);a&&!("get"in a?!t.__esModule:a.writable||a.configurable)||(a={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,a)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]};function y(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||g(t,e,n)}function b(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function v(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,a,o=n.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(r=o.next()).done;)i.push(r.value)}catch(l){a={error:l}}finally{try{r&&!r.done&&(n=o.return)&&n.call(o)}finally{if(a)throw a.error}}return i}function w(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(v(arguments[t]));return e}function k(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),a=0;for(t=0;t<n;t++)for(var o=arguments[t],i=0,l=o.length;i<l;i++,a++)r[a]=o[i];return r}function S(e,t,n){if(n||2===arguments.length)for(var r,a=0,o=t.length;a<o;a++)!r&&a in t||(r||(r=Array.prototype.slice.call(t,0,a)),r[a]=t[a]);return e.concat(r||Array.prototype.slice.call(t))}function x(e){return this instanceof x?(this.v=e,this):new x(e)}function _(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r,a=n.apply(e,t||[]),o=[];return r=Object.create(("function"==typeof AsyncIterator?AsyncIterator:Object).prototype),i("next"),i("throw"),i("return",(function(e){return function(t){return Promise.resolve(t).then(e,u)}})),r[Symbol.asyncIterator]=function(){return this},r;function i(e,t){a[e]&&(r[e]=function(t){return new Promise((function(n,r){o.push([e,t,n,r])>1||l(e,t)}))},t&&(r[e]=t(r[e])))}function l(e,t){try{(n=a[e](t)).value instanceof x?Promise.resolve(n.value.v).then(s,u):c(o[0][2],n)}catch(r){c(o[0][3],r)}var n}function s(e){l("next",e)}function u(e){l("throw",e)}function c(e,t){e(t),o.shift(),o.length&&l(o[0][0],o[0][1])}}function E(e){var t,n;return t={},r("next"),r("throw",(function(e){throw e})),r("return"),t[Symbol.iterator]=function(){return this},t;function r(r,a){t[r]=e[r]?function(t){return(n=!n)?{value:x(e[r](t)),done:!1}:a?a(t):t}:a}}function C(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=b(e),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise((function(r,a){(function(e,t,n,r){Promise.resolve(r).then((function(t){e({value:t,done:n})}),t)})(r,a,(t=e[n](t)).done,t.value)}))}}}function A(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}var T=Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t},L=function(e){return L=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},L(e)};function j(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n=L(e),r=0;r<n.length;r++)"default"!==n[r]&&g(t,e,n[r]);return T(t,e),t}function P(e){return e&&e.__esModule?e:{default:e}}function N(e,t,n,r){if("a"===n&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?r:"a"===n?r.call(e):r?r.value:t.get(e)}function O(e,t,n,r,a){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!a)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!a:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?a.call(e,n):a?a.value=n:t.set(e,n),n}function R(e,t){if(null===t||"object"!=typeof t&&"function"!=typeof t)throw new TypeError("Cannot use 'in' operator on non-object");return"function"==typeof e?t===e:e.has(t)}function M(e,t,n){if(null!=t){if("object"!=typeof t&&"function"!=typeof t)throw new TypeError("Object expected.");var r,a;if(n){if(!Symbol.asyncDispose)throw new TypeError("Symbol.asyncDispose is not defined.");r=t[Symbol.asyncDispose]}if(void 0===r){if(!Symbol.dispose)throw new TypeError("Symbol.dispose is not defined.");r=t[Symbol.dispose],n&&(a=r)}if("function"!=typeof r)throw new TypeError("Object not disposable.");a&&(r=function(){try{a.call(this)}catch(e){return Promise.reject(e)}}),e.stack.push({value:t,dispose:r,async:n})}else n&&e.stack.push({async:!0});return t}var D="function"==typeof SuppressedError?SuppressedError:function(e,t,n){var r=new Error(n);return r.name="SuppressedError",r.error=e,r.suppressed=t,r};function F(e){function t(t){e.error=e.hasError?new D(t,e.error,"An error was suppressed during disposal."):t,e.hasError=!0}var n,r=0;return function a(){for(;n=e.stack.pop();)try{if(!n.async&&1===r)return r=0,e.stack.push(n),Promise.resolve().then(a);if(n.dispose){var o=n.dispose.call(n.value);if(n.async)return r|=2,Promise.resolve(o).then(a,(function(e){return t(e),a()}))}else r|=1}catch(i){t(i)}if(1===r)return e.hasError?Promise.reject(e.error):Promise.resolve();if(e.hasError)throw e.error}()}function I(e,t){return"string"==typeof e&&/^\.\.?\//.test(e)?e.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i,(function(e,n,r,a,o){return n?t?".jsx":".js":!r||a&&o?r+a+"."+o.toLowerCase()+"js":e})):e}const B={__extends:a,__assign:o,__rest:i,__decorate:l,__param:s,__esDecorate:u,__runInitializers:c,__propKey:d,__setFunctionName:f,__metadata:p,__awaiter:m,__generator:h,__createBinding:g,__exportStar:y,__values:b,__read:v,__spread:w,__spreadArrays:k,__spreadArray:S,__await:x,__asyncGenerator:_,__asyncDelegator:E,__asyncValues:C,__makeTemplateObject:A,__importStar:j,__importDefault:P,__classPrivateFieldGet:N,__classPrivateFieldSet:O,__classPrivateFieldIn:R,__addDisposableResource:M,__disposeResources:F,__rewriteRelativeImportExtension:I}},1656:(e,t,n)=>{"use strict";n.d(t,{A:()=>At});var r=n(6540),a=n(4164),o=n(7489),i=n(5500),l=n(6347),s=n(1312),u=n(5062),c=n(4848);const d="__docusaurus_skipToContent_fallback";function f(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function p(){const e=(0,r.useRef)(null),{action:t}=(0,l.W6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&f(t)}),[]);return(0,u.$)((({location:n})=>{e.current&&!n.hash&&"PUSH"===t&&f(e.current)})),{containerRef:e,onClick:n}}const m=(0,s.T)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){const t=e.children??m,{containerRef:n,onClick:r}=p();return(0,c.jsx)("div",{ref:n,role:"region","aria-label":m,children:(0,c.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var g=n(7559),y=n(4090);const b={skipToContent:"skipToContent_fXgn"};function v(){return(0,c.jsx)(h,{className:b.skipToContent})}var w=n(6342),k=n(5041);function S({width:e=21,height:t=21,color:n="currentColor",strokeWidth:r=1.2,className:a,...o}){return(0,c.jsx)("svg",{viewBox:"0 0 15 15",width:e,height:t,...o,children:(0,c.jsx)("g",{stroke:n,strokeWidth:r,children:(0,c.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const x={closeButton:"closeButton_CVFx"};function _(e){return(0,c.jsx)("button",{type:"button","aria-label":(0,s.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,a.A)("clean-btn close",x.closeButton,e.className),children:(0,c.jsx)(S,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.p)(),{content:n}=t;return(0,c.jsx)("div",{...e,className:(0,a.A)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const A={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function T(){const{announcementBar:e}=(0,w.p)(),{isActive:t,close:n}=(0,k.M)();if(!t)return null;const{backgroundColor:r,textColor:o,isCloseable:i}=e;return(0,c.jsxs)("div",{className:(0,a.A)(g.G.announcementBar.container,A.announcementBar),style:{backgroundColor:r,color:o},role:"banner",children:[i&&(0,c.jsx)("div",{className:A.announcementBarPlaceholder}),(0,c.jsx)(C,{className:A.announcementBarContent}),i&&(0,c.jsx)(_,{onClick:n,className:A.announcementBarClose})]})}var L=n(9876),j=n(3104);var P=n(9532),N=n(5600);const O=r.createContext(null);function R({children:e}){const t=function(){const e=(0,L.M)(),t=(0,N.YL)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,P.ZC)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return(0,c.jsx)(O.Provider,{value:t,children:e})}function M(e){if(e.component){const t=e.component;return(0,c.jsx)(t,{...e.props})}}function D(){const e=(0,r.useContext)(O);if(!e)throw new P.dV("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,N.YL)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:M(o)})),[a,o,t])}function F(e){return parseInt(r.version.split(".")[0],10)<19?{inert:e?"":void 0}:{inert:e}}function I({children:e,inert:t}){return(0,c.jsx)("div",{className:(0,a.A)(g.G.layout.navbar.mobileSidebar.panel,"navbar-sidebar__item menu"),...F(t),children:e})}function B({header:e,primaryMenu:t,secondaryMenu:n}){const{shown:r}=D();return(0,c.jsxs)("div",{className:(0,a.A)(g.G.layout.navbar.mobileSidebar.container,"navbar-sidebar"),children:[e,(0,c.jsxs)("div",{className:(0,a.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":r}),children:[(0,c.jsx)(I,{inert:r,children:t}),(0,c.jsx)(I,{inert:!r,children:n})]})]})}var z=n(5293),$=n(2303);function U(e){return(0,c.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,c.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function q(e){return(0,c.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,c.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}function H(e){return(0,c.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,c.jsx)("path",{fill:"currentColor",d:"m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"})})}const G="toggle_vylO",V="toggleButton_gllP",W="toggleIcon_g3eP",Q="systemToggleIcon_QzmC",K="lightToggleIcon_pyhR",Y="darkToggleIcon_wfgR",X="toggleButtonDisabled_aARS";function Z(e){switch(e){case null:return(0,s.T)({message:"system mode",id:"theme.colorToggle.ariaLabel.mode.system",description:"The name for the system color mode"});case"light":return(0,s.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"});case"dark":return(0,s.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"});default:throw new Error(`unexpected color mode ${e}`)}}function J(e){return(0,s.T)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the color mode toggle"},{mode:Z(e)})}function ee(){return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(U,{"aria-hidden":!0,className:(0,a.A)(W,K)}),(0,c.jsx)(q,{"aria-hidden":!0,className:(0,a.A)(W,Y)}),(0,c.jsx)(H,{"aria-hidden":!0,className:(0,a.A)(W,Q)})]})}function te({className:e,buttonClassName:t,respectPrefersColorScheme:n,value:r,onChange:o}){const i=(0,$.A)();return(0,c.jsx)("div",{className:(0,a.A)(G,e),children:(0,c.jsx)("button",{className:(0,a.A)("clean-btn",V,!i&&X,t),type:"button",onClick:()=>o(function(e,t){if(!t)return"dark"===e?"light":"dark";switch(e){case null:return"light";case"light":return"dark";case"dark":return null;default:throw new Error(`unexpected color mode ${e}`)}}(r,n)),disabled:!i,title:Z(r),"aria-label":J(r),children:(0,c.jsx)(ee,{})})})}const ne=r.memo(te),re={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function ae({className:e}){const t=(0,w.p)().navbar.style,{disableSwitch:n,respectPrefersColorScheme:r}=(0,w.p)().colorMode,{colorModeChoice:a,setColorMode:o}=(0,z.G)();return n?null:(0,c.jsx)(ne,{className:e,buttonClassName:"dark"===t?re.darkNavbarColorModeToggle:void 0,respectPrefersColorScheme:r,value:a,onChange:o})}var oe=n(3465);function ie(){return(0,c.jsx)(oe.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function le(){const e=(0,L.M)();return(0,c.jsx)("button",{type:"button","aria-label":(0,s.T)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,c.jsx)(S,{color:"var(--ifm-color-emphasis-600)"})})}function se(){return(0,c.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,c.jsx)(ie,{}),(0,c.jsx)(ae,{className:"margin-right--md"}),(0,c.jsx)(le,{})]})}var ue=n(8774),ce=n(6025),de=n(6654);function fe(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var pe=n(3186);function me({activeBasePath:e,activeBaseRegex:t,to:n,href:r,label:a,html:o,isDropdownLink:i,prependBaseUrlToHref:l,...s}){const u=(0,ce.Ay)(n),d=(0,ce.Ay)(e),f=(0,ce.Ay)(r,{forcePrependBaseUrl:!0}),p=a&&r&&!(0,de.A)(r),m=o?{dangerouslySetInnerHTML:{__html:o}}:{children:(0,c.jsxs)(c.Fragment,{children:[a,p&&(0,c.jsx)(pe.A,{...i&&{width:12,height:12}})]})};return r?(0,c.jsx)(ue.A,{href:l?f:r,...s,...m}):(0,c.jsx)(ue.A,{to:u,isNavLink:!0,...(e||t)&&{isActive:(e,n)=>t?fe(t,n.pathname):n.pathname.startsWith(d)},...s,...m})}function he({className:e,isDropdownItem:t,...n}){return(0,c.jsx)("li",{className:"menu__list-item",children:(0,c.jsx)(me,{className:(0,a.A)("menu__link",e),...n})})}function ge({className:e,isDropdownItem:t=!1,...n}){const r=(0,c.jsx)(me,{className:(0,a.A)(t?"dropdown__link":"navbar__item navbar__link",e),isDropdownLink:t,...n});return t?(0,c.jsx)("li",{children:r}):r}function ye({mobile:e=!1,position:t,...n}){const r=e?he:ge;return(0,c.jsx)(r,{...n,activeClassName:n.activeClassName??(e?"menu__link--active":"navbar__link--active")})}var be=n(1422),ve=n(9169),we=n(4586);const ke="dropdownNavbarItemMobile_J0Sd";function Se(e,t){return e.some((e=>function(e,t){return!!(0,ve.ys)(e.to,t)||!!fe(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function xe({collapsed:e,onClick:t}){return(0,c.jsx)("button",{"aria-label":e?(0,s.T)({id:"theme.navbar.mobileDropdown.collapseButton.expandAriaLabel",message:"Expand the dropdown",description:"The ARIA label of the button to expand the mobile dropdown navbar item"}):(0,s.T)({id:"theme.navbar.mobileDropdown.collapseButton.collapseAriaLabel",message:"Collapse the dropdown",description:"The ARIA label of the button to collapse the mobile dropdown navbar item"}),"aria-expanded":!e,type:"button",className:"clean-btn menu__caret",onClick:t})}function _e({items:e,className:t,position:n,onClick:o,...i}){const s=function(){const{siteConfig:{baseUrl:e}}=(0,we.A)(),{pathname:t}=(0,l.zy)();return t.replace(e,"/")}(),u=(0,ve.ys)(i.to,s),d=Se(e,s),{collapsed:f,toggleCollapsed:p}=function({active:e}){const{collapsed:t,toggleCollapsed:n,setCollapsed:a}=(0,be.u)({initialState:()=>!e});return(0,r.useEffect)((()=>{e&&a(!1)}),[e,a]),{collapsed:t,toggleCollapsed:n}}({active:u||d}),m=i.to?void 0:"#";return(0,c.jsxs)("li",{className:(0,a.A)("menu__list-item",{"menu__list-item--collapsed":f}),children:[(0,c.jsxs)("div",{className:(0,a.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":u}),children:[(0,c.jsx)(me,{role:"button",className:(0,a.A)(ke,"menu__link menu__link--sublist",t),href:m,...i,onClick:e=>{"#"===m&&e.preventDefault(),p()},children:i.children??i.label}),(0,c.jsx)(xe,{collapsed:f,onClick:e=>{e.preventDefault(),p()}})]}),(0,c.jsx)(be.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:f,children:e.map(((e,t)=>(0,r.createElement)(Be,{mobile:!0,isDropdownItem:!0,onClick:o,activeClassName:"menu__link--active",...e,key:t})))})]})}function Ee({items:e,position:t,className:n,onClick:o,...i}){const l=(0,r.useRef)(null),[s,u]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{l.current&&!l.current.contains(e.target)&&u(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[l]),(0,c.jsxs)("div",{ref:l,className:(0,a.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===t,"dropdown--show":s}),children:[(0,c.jsx)(me,{"aria-haspopup":"true","aria-expanded":s,role:"button",href:i.to?void 0:"#",className:(0,a.A)("navbar__link",n),...i,onClick:i.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),u(!s))},children:i.children??i.label}),(0,c.jsx)("ul",{className:"dropdown__menu",children:e.map(((e,t)=>(0,r.createElement)(Be,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function Ce({mobile:e=!1,...t}){const n=e?_e:Ee;return(0,c.jsx)(n,{...t})}var Ae=n(2131);function Te({width:e=20,height:t=20,...n}){return(0,c.jsx)("svg",{viewBox:"0 0 24 24",width:e,height:t,"aria-hidden":!0,...n,children:(0,c.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const Le="iconLanguage_nlXk";var je=n(418);const Pe={navbarSearchContainer:"navbarSearchContainer_Bca1"};function Ne({children:e,className:t}){return(0,c.jsx)("div",{className:(0,a.A)(t,Pe.navbarSearchContainer),children:e})}var Oe=n(4070),Re=n(6972);var Me=n(3886);function De({docsPluginId:e,configs:t}){return function(e,t){if(t){const n=new Map(e.map((e=>[e.name,e]))),r=(t,r)=>{const a=n.get(t);if(!a)throw new Error(`No docs version exist for name '${t}', please verify your 'docsVersionDropdown' navbar item versions config.\nAvailable version names:\n- ${e.map((e=>`${e.name}`)).join("\n- ")}`);return{version:a,label:r?.label??a.label}};return Array.isArray(t)?t.map((e=>r(e,void 0))):Object.entries(t).map((([e,t])=>r(e,t)))}return e.map((e=>({version:e,label:e.label})))}((0,Oe.jh)(e),t)}function Fe(e,t){return t.alternateDocVersions[e.name]??function(e){return e.docs.find((t=>t.id===e.mainDocId))}(e)}const Ie={default:ye,localeDropdown:function({mobile:e,dropdownItemsBefore:t,dropdownItemsAfter:n,queryString:r="",...a}){const{i18n:{currentLocale:o,locales:i,localeConfigs:u}}=(0,we.A)(),d=(0,Ae.o)(),{search:f,hash:p}=(0,l.zy)(),m=[...t,...i.map((t=>{const n=`${`pathname://${d.createUrl({locale:t,fullyQualified:!1})}`}${f}${p}${r}`;return{label:u[t].label,lang:u[t].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:t===o?e?"menu__link--active":"dropdown__link--active":""}})),...n],h=e?(0,s.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):u[o].label;return(0,c.jsx)(Ce,{...a,mobile:e,label:(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(Te,{className:Le}),h]}),items:m})},search:function({mobile:e,className:t}){return e?null:(0,c.jsx)(Ne,{className:t,children:(0,c.jsx)(je.A,{})})},dropdown:Ce,html:function({value:e,className:t,mobile:n=!1,isDropdownItem:r=!1}){const o=r?"li":"div";return(0,c.jsx)(o,{className:(0,a.A)({navbar__item:!n&&!r,"menu__list-item":n},t),dangerouslySetInnerHTML:{__html:e}})},doc:function({docId:e,label:t,docsPluginId:n,...r}){const{activeDoc:a}=(0,Oe.zK)(n),o=(0,Re.QB)(e,n),i=a?.path===o?.path;return null===o||o.unlisted&&!i?null:(0,c.jsx)(ye,{exact:!0,...r,isActive:()=>i||!!a?.sidebar&&a.sidebar===o.sidebar,label:t??o.id,to:o.path})},docSidebar:function({sidebarId:e,label:t,docsPluginId:n,...r}){const{activeDoc:a}=(0,Oe.zK)(n),o=(0,Re.fW)(e,n).link;if(!o)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${e}" doesn't have anything to be linked to.`);return(0,c.jsx)(ye,{exact:!0,...r,isActive:()=>a?.sidebar===e,label:t??o.label,to:o.path})},docsVersion:function({label:e,to:t,docsPluginId:n,...r}){const a=(0,Re.Vd)(n)[0],o=e??a.label,i=t??(e=>e.docs.find((t=>t.id===e.mainDocId)))(a).path;return(0,c.jsx)(ye,{...r,label:o,to:i})},docsVersionDropdown:function({mobile:e,docsPluginId:t,dropdownActiveClassDisabled:n,dropdownItemsBefore:r,dropdownItemsAfter:a,versions:o,...i}){const{search:u,hash:d}=(0,l.zy)(),f=(0,Oe.zK)(t),{savePreferredVersionName:p}=(0,Me.g1)(t),m=De({docsPluginId:t,configs:o}),h=function({docsPluginId:e,versionItems:t}){return(0,Re.Vd)(e).map((e=>t.find((t=>t.version===e)))).filter((e=>void 0!==e))[0]??t[0]}({docsPluginId:t,versionItems:m}),g=[...r,...m.map((function({version:e,label:t}){return{label:t,to:`${Fe(e,f).path}${u}${d}`,isActive:()=>e===f.activeVersion,onClick:()=>p(e.name)}})),...a],y=e&&g.length>1?(0,s.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):h.label,b=e&&g.length>1?void 0:Fe(h.version,f).path;return g.length<=1?(0,c.jsx)(ye,{...i,mobile:e,label:y,to:b,isActive:n?()=>!1:void 0}):(0,c.jsx)(Ce,{...i,mobile:e,label:y,to:b,items:g,isActive:n?()=>!1:void 0})}};function Be({type:e,...t}){const n=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(e,t),r=Ie[n];if(!r)throw new Error(`No NavbarItem component found for type "${e}".`);return(0,c.jsx)(r,{...t})}function ze(){const e=(0,L.M)(),t=(0,w.p)().navbar.items;return(0,c.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(Be,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function $e(e){return(0,c.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,c.jsx)(s.A,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Ue(){const e=0===(0,w.p)().navbar.items.length,t=D();return(0,c.jsxs)(c.Fragment,{children:[!e&&(0,c.jsx)($e,{onClick:()=>t.hide()}),t.content]})}function qe(){const e=(0,L.M)();return function(e=!0){(0,r.useEffect)((()=>(document.body.style.overflow=e?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[e])}(e.shown),e.shouldRender?(0,c.jsx)(B,{header:(0,c.jsx)(se,{}),primaryMenu:(0,c.jsx)(ze,{}),secondaryMenu:(0,c.jsx)(Ue,{})}):null}const He={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Ge(e){return(0,c.jsx)("div",{role:"presentation",...e,className:(0,a.A)("navbar-sidebar__backdrop",e.className)})}function Ve({children:e}){const{navbar:{hideOnScroll:t,style:n}}=(0,w.p)(),o=(0,L.M)(),{navbarRef:i,isNavbarVisible:l}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,j.Mq)((({scrollY:t},r)=>{if(!e)return;if(t<o.current)return void n(!0);if(a.current)return void(a.current=!1);const i=r?.scrollY,l=document.documentElement.scrollHeight-o.current,s=window.innerHeight;i&&t>=i?n(!1):t+s<l&&n(!0)})),(0,u.$)((t=>{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(t);return(0,c.jsxs)("nav",{ref:i,"aria-label":(0,s.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.A)(g.G.layout.navbar.container,"navbar","navbar--fixed-top",t&&[He.navbarHideable,!l&&He.navbarHidden],{"navbar--dark":"dark"===n,"navbar--primary":"primary"===n,"navbar-sidebar--show":o.shown}),children:[e,(0,c.jsx)(Ge,{onClick:o.toggle}),(0,c.jsx)(qe,{})]})}var We=n(440);const Qe={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};function Ke(e){return(0,c.jsx)("button",{type:"button",...e,children:(0,c.jsx)(s.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function Ye({error:e}){const t=(0,We.rA)(e).map((e=>e.message)).join("\n\nCause:\n");return(0,c.jsx)("p",{className:Qe.errorBoundaryError,children:t})}class Xe extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const Ze="right";function Je({width:e=30,height:t=30,className:n,...r}){return(0,c.jsx)("svg",{className:n,width:e,height:t,viewBox:"0 0 30 30","aria-hidden":"true",...r,children:(0,c.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function et(){const{toggle:e,shown:t}=(0,L.M)();return(0,c.jsx)("button",{onClick:e,"aria-label":(0,s.T)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,c.jsx)(Je,{})})}const tt={colorModeToggle:"colorModeToggle_DEke"};function nt({items:e}){return(0,c.jsx)(c.Fragment,{children:e.map(((e,t)=>(0,c.jsx)(Xe,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,c.jsx)(Be,{...e})},t)))})}function rt({left:e,right:t}){return(0,c.jsxs)("div",{className:"navbar__inner",children:[(0,c.jsx)("div",{className:(0,a.A)(g.G.layout.navbar.containerLeft,"navbar__items"),children:e}),(0,c.jsx)("div",{className:(0,a.A)(g.G.layout.navbar.containerRight,"navbar__items navbar__items--right"),children:t})]})}function at(){const e=(0,L.M)(),t=(0,w.p)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??Ze)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),a=t.find((e=>"search"===e.type));return(0,c.jsx)(rt,{left:(0,c.jsxs)(c.Fragment,{children:[!e.disabled&&(0,c.jsx)(et,{}),(0,c.jsx)(ie,{}),(0,c.jsx)(nt,{items:n})]}),right:(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(nt,{items:r}),(0,c.jsx)(ae,{className:tt.colorModeToggle}),!a&&(0,c.jsx)(Ne,{children:(0,c.jsx)(je.A,{})})]})})}function ot(){return(0,c.jsx)(Ve,{children:(0,c.jsx)(at,{})})}function it({item:e}){const{to:t,href:n,label:r,prependBaseUrlToHref:o,className:i,...l}=e,s=(0,ce.Ay)(t),u=(0,ce.Ay)(n,{forcePrependBaseUrl:!0});return(0,c.jsxs)(ue.A,{className:(0,a.A)("footer__link-item",i),...n?{href:o?u:n}:{to:s},...l,children:[r,n&&!(0,de.A)(n)&&(0,c.jsx)(pe.A,{})]})}function lt({item:e}){return e.html?(0,c.jsx)("li",{className:(0,a.A)("footer__item",e.className),dangerouslySetInnerHTML:{__html:e.html}}):(0,c.jsx)("li",{className:"footer__item",children:(0,c.jsx)(it,{item:e})},e.href??e.to)}function st({column:e}){return(0,c.jsxs)("div",{className:(0,a.A)(g.G.layout.footer.column,"col footer__col",e.className),children:[(0,c.jsx)("div",{className:"footer__title",children:e.title}),(0,c.jsx)("ul",{className:"footer__items clean-list",children:e.items.map(((e,t)=>(0,c.jsx)(lt,{item:e},t)))})]})}function ut({columns:e}){return(0,c.jsx)("div",{className:"row footer__links",children:e.map(((e,t)=>(0,c.jsx)(st,{column:e},t)))})}function ct(){return(0,c.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function dt({item:e}){return e.html?(0,c.jsx)("span",{className:(0,a.A)("footer__link-item",e.className),dangerouslySetInnerHTML:{__html:e.html}}):(0,c.jsx)(it,{item:e})}function ft({links:e}){return(0,c.jsx)("div",{className:"footer__links text--center",children:(0,c.jsx)("div",{className:"footer__links",children:e.map(((t,n)=>(0,c.jsxs)(r.Fragment,{children:[(0,c.jsx)(dt,{item:t}),e.length!==n+1&&(0,c.jsx)(ct,{})]},n)))})})}function pt({links:e}){return function(e){return"title"in e[0]}(e)?(0,c.jsx)(ut,{columns:e}):(0,c.jsx)(ft,{links:e})}var mt=n(1122);const ht="footerLogoLink_BH7S";function gt({logo:e}){const{withBaseUrl:t}=(0,ce.hH)(),n={light:t(e.src),dark:t(e.srcDark??e.src)};return(0,c.jsx)(mt.A,{className:(0,a.A)("footer__logo",e.className),alt:e.alt,sources:n,width:e.width,height:e.height,style:e.style})}function yt({logo:e}){return e.href?(0,c.jsx)(ue.A,{href:e.href,className:ht,target:e.target,children:(0,c.jsx)(gt,{logo:e})}):(0,c.jsx)(gt,{logo:e})}function bt({copyright:e}){return(0,c.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:e}})}function vt({style:e,links:t,logo:n,copyright:r}){return(0,c.jsx)("footer",{className:(0,a.A)(g.G.layout.footer.container,"footer",{"footer--dark":"dark"===e}),children:(0,c.jsxs)("div",{className:"container container-fluid",children:[t,(n||r)&&(0,c.jsxs)("div",{className:"footer__bottom text--center",children:[n&&(0,c.jsx)("div",{className:"margin-bottom--sm",children:n}),r]})]})})}function wt(){const{footer:e}=(0,w.p)();if(!e)return null;const{copyright:t,links:n,logo:r,style:a}=e;return(0,c.jsx)(vt,{style:a,links:n&&n.length>0&&(0,c.jsx)(pt,{links:n}),logo:r&&(0,c.jsx)(yt,{logo:r}),copyright:t&&(0,c.jsx)(bt,{copyright:t})})}const kt=r.memo(wt),St=(0,P.fM)([z.a,k.o,j.Tv,Me.VQ,i.Jx,function({children:e}){return(0,c.jsx)(N.y_,{children:(0,c.jsx)(L.e,{children:(0,c.jsx)(R,{children:e})})})}]);function xt({children:e}){return(0,c.jsx)(St,{children:e})}var _t=n(1107);function Et({error:e,tryAgain:t}){return(0,c.jsx)("main",{className:"container margin-vert--xl",children:(0,c.jsx)("div",{className:"row",children:(0,c.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,c.jsx)(_t.A,{as:"h1",className:"hero__title",children:(0,c.jsx)(s.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,c.jsx)("div",{className:"margin-vert--lg",children:(0,c.jsx)(Ke,{onClick:t,className:"button button--primary shadow--lw"})}),(0,c.jsx)("hr",{}),(0,c.jsx)("div",{className:"margin-vert--md",children:(0,c.jsx)(Ye,{error:e})})]})})})}const Ct={mainWrapper:"mainWrapper_z2l0"};function At(e){const{children:t,noFooter:n,wrapperClassName:r,title:l,description:s}=e;return(0,y.J)(),(0,c.jsxs)(xt,{children:[(0,c.jsx)(i.be,{title:l,description:s}),(0,c.jsx)(v,{}),(0,c.jsx)(T,{}),(0,c.jsx)(ot,{}),(0,c.jsx)("div",{id:d,className:(0,a.A)(g.G.layout.main.container,g.G.wrapper.main,Ct.mainWrapper,r),children:(0,c.jsx)(o.A,{fallback:e=>(0,c.jsx)(Et,{...e}),children:t})}),!n&&(0,c.jsx)(kt,{})]})}},1682:(e,t,n)=>{"use strict";function r(e){return Array.from(new Set(e))}function a(e,t){const n={};let r=0;for(const a of e){const e=t(a,r);n[e]??=[],n[e].push(a),r+=1}return n}n.d(t,{$z:()=>a,sb:()=>r})},1765:(e,t,n)=>{"use strict";n.d(t,{My:()=>A,f4:()=>ne});var r,a,o,i,l,s,u,c=n(6540),d=n(4164),f=Object.create,p=Object.defineProperty,m=Object.defineProperties,h=Object.getOwnPropertyDescriptor,g=Object.getOwnPropertyDescriptors,y=Object.getOwnPropertyNames,b=Object.getOwnPropertySymbols,v=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty,k=Object.prototype.propertyIsEnumerable,S=(e,t,n)=>t in e?p(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,x=(e,t)=>{for(var n in t||(t={}))w.call(t,n)&&S(e,n,t[n]);if(b)for(var n of b(t))k.call(t,n)&&S(e,n,t[n]);return e},_=(e,t)=>m(e,g(t)),E=(e,t)=>{var n={};for(var r in e)w.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&b)for(var r of b(e))t.indexOf(r)<0&&k.call(e,r)&&(n[r]=e[r]);return n},C=(r={"../../node_modules/.pnpm/prismjs@1.29.0_patch_hash=vrxx3pzkik6jpmgpayxfjunetu/node_modules/prismjs/prism.js"(e,t){var n=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var a,o;switch(n=n||{},r.util.type(t)){case"Object":if(o=r.util.objId(t),n[o])return n[o];for(var i in a={},n[o]=a,t)t.hasOwnProperty(i)&&(a[i]=e(t[i],n));return a;case"Array":return o=r.util.objId(t),n[o]?n[o]:(a=[],n[o]=a,t.forEach((function(t,r){a[r]=e(t,n)})),a);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var r="no-"+t;e;){var a=e.classList;if(a.contains(t))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=r.util.clone(r.languages[e]);for(var a in t)n[a]=t[a];return n},insertBefore:function(e,t,n,a){var o=(a=a||r.languages)[e],i={};for(var l in o)if(o.hasOwnProperty(l)){if(l==t)for(var s in n)n.hasOwnProperty(s)&&(i[s]=n[s]);n.hasOwnProperty(l)||(i[l]=o[l])}var u=a[e];return a[e]=i,r.languages.DFS(r.languages,(function(t,n){n===u&&t!=e&&(this[t]=i)})),i},DFS:function e(t,n,a,o){o=o||{};var i=r.util.objId;for(var l in t)if(t.hasOwnProperty(l)){n.call(t,l,t[l],a||l);var s=t[l],u=r.util.type(s);"Object"!==u||o[i(s)]?"Array"!==u||o[i(s)]||(o[i(s)]=!0,e(s,n,l,o)):(o[i(s)]=!0,e(s,n,null,o))}}},plugins:{},highlight:function(e,t,n){var o={code:e,grammar:t,language:n};if(r.hooks.run("before-tokenize",o),!o.grammar)throw new Error('The language "'+o.language+'" has no grammar.');return o.tokens=r.tokenize(o.code,o.grammar),r.hooks.run("after-tokenize",o),a.stringify(r.util.encode(o.tokens),o.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var a=new l;return s(a,a.head,e),i(e,a,t,a.head,0),function(e){for(var t=[],n=e.head.next;n!==e.tail;)t.push(n.value),n=n.next;return t}(a)},hooks:{all:{},add:function(e,t){var n=r.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=r.hooks.all[e];if(n&&n.length)for(var a,o=0;a=n[o++];)a(t)}},Token:a};function a(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function o(e,t,n,r){e.lastIndex=t;var a=e.exec(n);if(a&&r&&a[1]){var o=a[1].length;a.index+=o,a[0]=a[0].slice(o)}return a}function i(e,t,n,l,c,d){for(var f in n)if(n.hasOwnProperty(f)&&n[f]){var p=n[f];p=Array.isArray(p)?p:[p];for(var m=0;m<p.length;++m){if(d&&d.cause==f+","+m)return;var h=p[m],g=h.inside,y=!!h.lookbehind,b=!!h.greedy,v=h.alias;if(b&&!h.pattern.global){var w=h.pattern.toString().match(/[imsuy]*$/)[0];h.pattern=RegExp(h.pattern.source,w+"g")}for(var k=h.pattern||h,S=l.next,x=c;S!==t.tail&&!(d&&x>=d.reach);x+=S.value.length,S=S.next){var _=S.value;if(t.length>e.length)return;if(!(_ instanceof a)){var E,C=1;if(b){if(!(E=o(k,x,e,y))||E.index>=e.length)break;var A=E.index,T=E.index+E[0].length,L=x;for(L+=S.value.length;A>=L;)L+=(S=S.next).value.length;if(x=L-=S.value.length,S.value instanceof a)continue;for(var j=S;j!==t.tail&&(L<T||"string"==typeof j.value);j=j.next)C++,L+=j.value.length;C--,_=e.slice(x,L),E.index-=x}else if(!(E=o(k,0,_,y)))continue;A=E.index;var P=E[0],N=_.slice(0,A),O=_.slice(A+P.length),R=x+_.length;d&&R>d.reach&&(d.reach=R);var M=S.prev;if(N&&(M=s(t,M,N),x+=N.length),u(t,M,C),S=s(t,M,new a(f,g?r.tokenize(P,g):P,v,P)),O&&s(t,S,O),C>1){var D={cause:f+","+m,reach:R};i(e,t,n,S.prev,x,D),d&&D.reach>d.reach&&(d.reach=D.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function s(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function u(e,t,n){for(var r=t.next,a=0;a<n&&r!==e.tail;a++)r=r.next;t.next=r,r.prev=t,e.length-=a}return a.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var a="";return t.forEach((function(t){a+=e(t,n)})),a}var o={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},i=t.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(o.classes,i):o.classes.push(i)),r.hooks.run("wrap",o);var l="";for(var s in o.attributes)l+=" "+s+'="'+(o.attributes[s]||"").replace(/"/g,""")+'"';return"<"+o.tag+' class="'+o.classes.join(" ")+'"'+l+">"+o.content+"</"+o.tag+">"},r}();t.exports=n,n.default=n}},function(){return a||(0,r[y(r)[0]])((a={exports:{}}).exports,a),a.exports}),A=((e,t,n)=>(n=null!=e?f(v(e)):{},((e,t,n,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let a of y(t))w.call(e,a)||a===n||p(e,a,{get:()=>t[a],enumerable:!(r=h(t,a))||r.enumerable});return e})(!t&&e&&e.__esModule?n:p(n,"default",{value:e,enumerable:!0}),e)))(C());A.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},A.languages.markup.tag.inside["attr-value"].inside.entity=A.languages.markup.entity,A.languages.markup.doctype.inside["internal-subset"].inside=A.languages.markup,A.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(A.languages.markup.tag,"addInlined",{value:function(e,t){var n;(t=((n=((n={})["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:A.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i,{"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}}))["language-"+t]={pattern:/[\s\S]+/,inside:A.languages[t]},{}))[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:n},A.languages.insertBefore("markup","cdata",t)}}),Object.defineProperty(A.languages.markup.tag,"addAttribute",{value:function(e,t){A.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:A.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),A.languages.html=A.languages.markup,A.languages.mathml=A.languages.markup,A.languages.svg=A.languages.markup,A.languages.xml=A.languages.extend("markup",{}),A.languages.ssml=A.languages.xml,A.languages.atom=A.languages.xml,A.languages.rss=A.languages.xml,o=A,i={pattern:/\\[\\(){}[\]^$+*?|.]/,alias:"escape"},s="(?:[^\\\\-]|"+(l=/\\(?:x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|0[0-7]{0,2}|[123][0-7]{2}|c[a-zA-Z]|.)/).source+")",s=RegExp(s+"-"+s),u={pattern:/(<|')[^<>']+(?=[>']$)/,lookbehind:!0,alias:"variable"},o.languages.regex={"char-class":{pattern:/((?:^|[^\\])(?:\\\\)*)\[(?:[^\\\]]|\\[\s\S])*\]/,lookbehind:!0,inside:{"char-class-negation":{pattern:/(^\[)\^/,lookbehind:!0,alias:"operator"},"char-class-punctuation":{pattern:/^\[|\]$/,alias:"punctuation"},range:{pattern:s,inside:{escape:l,"range-punctuation":{pattern:/-/,alias:"operator"}}},"special-escape":i,"char-set":{pattern:/\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},escape:l}},"special-escape":i,"char-set":{pattern:/\.|\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},backreference:[{pattern:/\\(?![123][0-7]{2})[1-9]/,alias:"keyword"},{pattern:/\\k<[^<>']+>/,alias:"keyword",inside:{"group-name":u}}],anchor:{pattern:/[$^]|\\[ABbGZz]/,alias:"function"},escape:l,group:[{pattern:/\((?:\?(?:<[^<>']+>|'[^<>']+'|[>:]|<?[=!]|[idmnsuxU]+(?:-[idmnsuxU]+)?:?))?/,alias:"punctuation",inside:{"group-name":u}},{pattern:/\)/,alias:"punctuation"}],quantifier:{pattern:/(?:[+*?]|\{\d+(?:,\d*)?\})[?+]?/,alias:"number"},alternation:{pattern:/\|/,alias:"keyword"}},A.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},A.languages.javascript=A.languages.extend("clike",{"class-name":[A.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),A.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,A.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:A.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:A.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:A.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:A.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:A.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),A.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:A.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),A.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),A.languages.markup&&(A.languages.markup.tag.addInlined("script","javascript"),A.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),A.languages.js=A.languages.javascript,A.languages.actionscript=A.languages.extend("javascript",{keyword:/\b(?:as|break|case|catch|class|const|default|delete|do|dynamic|each|else|extends|final|finally|for|function|get|if|implements|import|in|include|instanceof|interface|internal|is|namespace|native|new|null|override|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|use|var|void|while|with)\b/,operator:/\+\+|--|(?:[+\-*\/%^]|&&?|\|\|?|<<?|>>?>?|[!=]=?)=?|[~?@]/}),A.languages.actionscript["class-name"].alias="function",delete A.languages.actionscript.parameter,delete A.languages.actionscript["literal-property"],A.languages.markup&&A.languages.insertBefore("actionscript","string",{xml:{pattern:/(^|[^.])<\/?\w+(?:\s+[^\s>\/=]+=("|')(?:\\[\s\S]|(?!\2)[^\\])*\2)*\s*\/?>/,lookbehind:!0,inside:A.languages.markup}}),function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(A),function(e){var t=e.languages.javadoclike={parameter:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*@(?:arg|arguments|param)\s+)\w+/m,lookbehind:!0},keyword:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*|\{)@[a-z][a-zA-Z-]+\b/m,lookbehind:!0},punctuation:/[{}]/};Object.defineProperty(t,"addSupport",{value:function(t,n){(t="string"==typeof t?[t]:t).forEach((function(t){var r=function(e){e.inside||(e.inside={}),e.inside.rest=n},a="doc-comment";if(o=e.languages[t]){var o,i=o[a];if((i=i||(o=e.languages.insertBefore(t,"comment",{"doc-comment":{pattern:/(^|[^\\])\/\*\*[^/][\s\S]*?(?:\*\/|$)/,lookbehind:!0,alias:"comment"}}))[a])instanceof RegExp&&(i=o[a]={pattern:i}),Array.isArray(i))for(var l=0,s=i.length;l<s;l++)i[l]instanceof RegExp&&(i[l]={pattern:i[l]}),r(i[l]);else r(i)}}))}}),t.addSupport(["java","javascript","php"],t)}(A),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;(t=(e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css,e.languages.markup))&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(A),function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,n=(t=(e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+t.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[t,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}}),{pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0}),{pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0});e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|RebeccaPurple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,number:n})}(A),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<key>>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(A),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source,i=(e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n<r;n++){var a,o=t[n];"code"!==o.type?e(o.content):(a=o.content[1],o=o.content[3],a&&o&&"code-language"===a.type&&"code-block"===o.type&&"string"==typeof a.content&&(a=a.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),a="language-"+(a=(/[a-z][\w-]*/i.exec(a)||[""])[0].toLowerCase()),o.alias?"string"==typeof o.alias?o.alias=[o.alias,a]:o.alias.push(a):o.alias=[a]))}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",r=0,a=t.classes.length;r<a;r++){var o=t.classes[r];if(o=/language-(.+)/.exec(o)){n=o[1];break}}var u,c=e.languages[n];c?t.content=e.highlight(t.content.replace(i,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;return"#"===(t=t.toLowerCase())[0]?(n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),s(n)):l[t]||e})),c,n):n&&"none"!==n&&e.plugins.autoloader&&(u="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random()),t.attributes.id=u,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(u);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))})))}})),RegExp(e.languages.markup.tag.pattern.source,"gi")),l={amp:"&",lt:"<",gt:">",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(A),A.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:A.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},A.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var r=t[n++];if("keyword"===r.type&&"mutation"===r.content){var a=[];if(d(["definition-mutation","punctuation"])&&"("===c(1).content){n+=2;var o=f(/^\($/,/^\)$/);if(-1===o)continue;for(;n<o;n++){var i=c(0);"variable"===i.type&&(p(i,"variable-input"),a.push(i.content))}n=o+1}if(d(["punctuation","property-query"])&&"{"===c(0).content&&(n++,p(c(0),"property-mutation"),0<a.length)){var l=f(/^\{$/,/^\}$/);if(-1!==l)for(var s=n;s<l;s++){var u=t[s];"variable"===u.type&&0<=a.indexOf(u.content)&&p(u,"variable-input")}}}}function c(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n<e.length;n++){var r=c(n+t);if(!r||r.type!==e[n])return}return 1}function f(e,r){for(var a=1,o=n;o<t.length;o++){var i=t[o],l=i.content;if("punctuation"===i.type&&"string"==typeof l)if(e.test(l))a++;else if(r.test(l)&&0===--a)return o}return-1}function p(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),A.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(t,n,r){return t={code:t,grammar:n,language:r},e.hooks.run("before-tokenize",t),t.tokens=e.tokenize(t.code,t.grammar),e.hooks.run("after-tokenize",t),t.tokens}function s(t,n,i){var s=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),u=0,c={},d=(s=l(s.map((function(e){if("string"==typeof e)return e;var n,r;for(e=e.content;-1!==t.indexOf((r=u++,n="___"+i.toUpperCase()+"_"+r+"___")););return c[n]=e,n})).join(""),n,i),Object.keys(c));return u=0,function t(n){for(var o=0;o<n.length;o++){if(u>=d.length)return;var i,s,f,p,m,h,g,y=n[o];"string"==typeof y||"string"==typeof y.content?(i=d[u],-1!==(g=(h="string"==typeof y?y:y.content).indexOf(i))&&(++u,s=h.substring(0,g),m=c[i],f=void 0,(p={})["interpolation-punctuation"]=a,3===(p=e.tokenize(m,p)).length&&((f=[1,1]).push.apply(f,l(p[1],e.languages.javascript,"javascript")),p.splice.apply(p,f)),f=new e.Token("interpolation",p,r.alias,m),p=h.substring(g+i.length),m=[],s&&m.push(s),m.push(f),p&&(t(h=[p]),m.push.apply(m,h)),"string"==typeof y?(n.splice.apply(n,[o,1].concat(m)),o+=m.length-1):y.content=m)):(g=y.content,Array.isArray(g)?t(g):t([g]))}}(s),new e.Token(i,s,"language-"+i,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var u={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function c(e){return"string"==typeof e?e:Array.isArray(e)?e.map(c).join(""):c(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in u&&function t(n){for(var r=0,a=n.length;r<a;r++){var o,i,l,u=n[r];"string"!=typeof u&&(o=u.content,Array.isArray(o)?"template-string"===u.type?(u=o[1],3===o.length&&"string"!=typeof u&&"embedded-code"===u.type&&(i=c(u),u=u.alias,u=Array.isArray(u)?u[0]:u,l=e.languages[u])&&(o[1]=s(i,l,u))):t(o):"string"!=typeof o&&t([o]))}}(t.tokens)}))}(A),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(A),function(e){var t=e.languages.javascript,n=/\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})+\}/.source,r="(@(?:arg|argument|param|property)\\s+(?:"+n+"\\s+)?)";e.languages.jsdoc=e.languages.extend("javadoclike",{parameter:{pattern:RegExp(r+/(?:(?!\s)[$\w\xA0-\uFFFF.])+(?=\s|$)/.source),lookbehind:!0,inside:{punctuation:/\./}}}),e.languages.insertBefore("jsdoc","keyword",{"optional-parameter":{pattern:RegExp(r+/\[(?:(?!\s)[$\w\xA0-\uFFFF.])+(?:=[^[\]]+)?\](?=\s|$)/.source),lookbehind:!0,inside:{parameter:{pattern:/(^\[)[$\w\xA0-\uFFFF\.]+/,lookbehind:!0,inside:{punctuation:/\./}},code:{pattern:/(=)[\s\S]*(?=\]$)/,lookbehind:!0,inside:t,alias:"language-javascript"},punctuation:/[=[\]]/}},"class-name":[{pattern:RegExp(/(@(?:augments|class|extends|interface|memberof!?|template|this|typedef)\s+(?:<TYPE>\s+)?)[A-Z]\w*(?:\.[A-Z]\w*)*/.source.replace(/<TYPE>/g,(function(){return n}))),lookbehind:!0,inside:{punctuation:/\./}},{pattern:RegExp("(@[a-z]+\\s+)"+n),lookbehind:!0,inside:{string:t.string,number:t.number,boolean:t.boolean,keyword:e.languages.typescript.keyword,operator:/=>|\.\.\.|[&|?:*]/,punctuation:/[.,;=<>{}()[\]]/}}],example:{pattern:/(@example\s+(?!\s))(?:[^@\s]|\s+(?!\s))+?(?=\s*(?:\*\s*)?(?:@\w|\*\/))/,lookbehind:!0,inside:{code:{pattern:/^([\t ]*(?:\*\s*)?)\S.*$/m,lookbehind:!0,inside:t,alias:"language-javascript"}}}}),e.languages.javadoclike.addSupport("javascript",e.languages.jsdoc)}(A),function(e){e.languages.flow=e.languages.extend("javascript",{}),e.languages.insertBefore("flow","keyword",{type:[{pattern:/\b(?:[Bb]oolean|Function|[Nn]umber|[Ss]tring|[Ss]ymbol|any|mixed|null|void)\b/,alias:"class-name"}]}),e.languages.flow["function-variable"].pattern=/(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/i,delete e.languages.flow.parameter,e.languages.insertBefore("flow","operator",{"flow-punctuation":{pattern:/\{\||\|\}/,alias:"punctuation"}}),Array.isArray(e.languages.flow.keyword)||(e.languages.flow.keyword=[e.languages.flow.keyword]),e.languages.flow.keyword.unshift({pattern:/(^|[^$]\b)(?:Class|declare|opaque|type)\b(?!\$)/,lookbehind:!0},{pattern:/(^|[^$]\B)\$(?:Diff|Enum|Exact|Keys|ObjMap|PropertyType|Record|Shape|Subtype|Supertype|await)\b(?!\$)/,lookbehind:!0})}(A),A.languages.n4js=A.languages.extend("javascript",{keyword:/\b(?:Array|any|boolean|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|module|new|null|number|package|private|protected|public|return|set|static|string|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/}),A.languages.insertBefore("n4js","constant",{annotation:{pattern:/@+\w+/,alias:"operator"}}),A.languages.n4jsd=A.languages.n4js,function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r<n.length;r++){var a=n[r],o=e.languages.javascript[a];a=(o="RegExp"===e.util.type(o)?e.languages.javascript[a]={pattern:o}:o).inside||{};(o.inside=a)["maybe-class-name"]=/^[A-Z][\s\S]*/}}(A),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,a=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function o(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return r})).replace(/<SPREAD>/g,(function(){return a})),RegExp(e,t)}function i(t){for(var n=[],r=0;r<t.length;r++){var a=t[r],o=!1;"string"!=typeof a&&("tag"===a.type&&a.content[0]&&"tag"===a.content[0].type?"</"===a.content[0].content[0].content?0<n.length&&n[n.length-1].tagName===l(a.content[0].content[1])&&n.pop():"/>"!==a.content[a.content.length-1].content&&n.push({tagName:l(a.content[0].content[1]),openedBraces:0}):0<n.length&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:0<n.length&&0<n[n.length-1].openedBraces&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&0<n.length&&0===n[n.length-1].openedBraces&&(o=l(a),r<t.length-1&&("string"==typeof t[r+1]||"plain-text"===t[r+1].type)&&(o+=l(t[r+1]),t.splice(r+1,1)),0<r&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(o=l(t[r-1])+o,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",o,null,o)),a.content&&"string"!=typeof a.content&&i(a.content)}}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var l=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(l).join(""):""};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||i(e.tokens)}))}(A),function(e){var t=e.util.clone(e.languages.typescript);(t=(e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"],e.languages.tsx.tag)).pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+t.pattern.source+")",t.pattern.flags),t.lookbehind=!0}(A),A.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp(/(^|[^"#])/.source+"(?:"+/"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source+"|"+/"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source+")"+/(?!["#])/.source),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp(/(^|[^"#])(#+)/.source+"(?:"+/"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source+"|"+/"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source+")\\2"),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp(/#/.source+"(?:"+/(?:elseif|if)\b/.source+"(?:[ \t]*"+/(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source+")+|"+/(?:else|endif)\b/.source+")"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},A.languages.swift["string-literal"].forEach((function(e){e.inside.interpolation.inside=A.languages.swift})),function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(A),A.languages.c=A.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),A.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),A.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},A.languages.c.string],char:A.languages.c.char,comment:A.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:A.languages.c}}}}),A.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete A.languages.c.boolean,A.languages.objectivec=A.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete A.languages.objectivec["class-name"],A.languages.objc=A.languages.objectivec,A.languages.reason=A.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),A.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete A.languages.reason.function,function(e){for(var t=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source,n=0;n<2;n++)t=t.replace(/<self>/g,(function(){return t}));t=t.replace(/<self>/g,(function(){return/[^\s\S]/.source})),e.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(A),A.languages.go=A.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),A.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete A.languages.go["class-name"],function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(A),A.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},A.languages.python["string-interpolation"].inside.interpolation.inside.rest=A.languages.python,A.languages.py=A.languages.python,A.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},A.languages.webmanifest=A.languages.json;((e,t)=>{for(var n in t)p(e,n,{get:t[n],enumerable:!0})})({},{dracula:()=>T,duotoneDark:()=>L,duotoneLight:()=>j,github:()=>P,gruvboxMaterialDark:()=>Q,gruvboxMaterialLight:()=>K,jettwaveDark:()=>H,jettwaveLight:()=>G,nightOwl:()=>N,nightOwlLight:()=>O,oceanicNext:()=>D,okaidia:()=>F,oneDark:()=>V,oneLight:()=>W,palenight:()=>I,shadesOfPurple:()=>B,synthwave84:()=>z,ultramin:()=>$,vsDark:()=>U,vsLight:()=>q});var T={plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},L={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]},j={plain:{backgroundColor:"#faf8f5",color:"#728fcb"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#b6ad9a"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#063289"}},{types:["property","function"],style:{color:"#b29762"}},{types:["tag-id","selector","atrule-id"],style:{color:"#2d2006"}},{types:["attr-name"],style:{color:"#896724"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule"],style:{color:"#728fcb"}},{types:["placeholder","variable"],style:{color:"#93abdc"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#896724"}}]},P={plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},N={plain:{color:"#d6deeb",backgroundColor:"#011627"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(99, 119, 119)",fontStyle:"italic"}},{types:["string","url"],style:{color:"rgb(173, 219, 103)"}},{types:["variable"],style:{color:"rgb(214, 222, 235)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation"],style:{color:"rgb(199, 146, 234)"}},{types:["selector","doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(255, 203, 139)"}},{types:["tag","operator","keyword"],style:{color:"rgb(127, 219, 202)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["property"],style:{color:"rgb(128, 203, 196)"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}}]},O={plain:{color:"#403f53",backgroundColor:"#FBFBFB"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(72, 118, 214)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(152, 159, 177)",fontStyle:"italic"}},{types:["string","builtin","char","constant","url"],style:{color:"rgb(72, 118, 214)"}},{types:["variable"],style:{color:"rgb(201, 103, 101)"}},{types:["number"],style:{color:"rgb(170, 9, 130)"}},{types:["punctuation"],style:{color:"rgb(153, 76, 195)"}},{types:["function","selector","doctype"],style:{color:"rgb(153, 76, 195)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(17, 17, 17)"}},{types:["tag"],style:{color:"rgb(153, 76, 195)"}},{types:["operator","property","keyword","namespace"],style:{color:"rgb(12, 150, 155)"}},{types:["boolean"],style:{color:"rgb(188, 84, 84)"}}]},R="#c5a5c5",M="#8dc891",D={plain:{backgroundColor:"#282c34",color:"#ffffff"},styles:[{types:["attr-name"],style:{color:R}},{types:["attr-value"],style:{color:M}},{types:["comment","block-comment","prolog","doctype","cdata","shebang"],style:{color:"#999999"}},{types:["property","number","function-name","constant","symbol","deleted"],style:{color:"#5a9bcf"}},{types:["boolean"],style:{color:"#ff8b50"}},{types:["tag"],style:{color:"#fc929e"}},{types:["string"],style:{color:M}},{types:["punctuation"],style:{color:M}},{types:["selector","char","builtin","inserted"],style:{color:"#D8DEE9"}},{types:["function"],style:{color:"#79b6f2"}},{types:["operator","entity","url","variable"],style:{color:"#d7deea"}},{types:["keyword"],style:{color:R}},{types:["atrule","class-name"],style:{color:"#FAC863"}},{types:["important"],style:{fontWeight:"400"}},{types:["bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}}]},F={plain:{color:"#f8f8f2",backgroundColor:"#272822"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"#f92672",fontStyle:"italic"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"#8292a2",fontStyle:"italic"}},{types:["string","url"],style:{color:"#a6e22e"}},{types:["variable"],style:{color:"#f8f8f2"}},{types:["number"],style:{color:"#ae81ff"}},{types:["builtin","char","constant","function","class-name"],style:{color:"#e6db74"}},{types:["punctuation"],style:{color:"#f8f8f2"}},{types:["selector","doctype"],style:{color:"#a6e22e",fontStyle:"italic"}},{types:["tag","operator","keyword"],style:{color:"#66d9ef"}},{types:["boolean"],style:{color:"#ae81ff"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)",opacity:.7}},{types:["tag","property"],style:{color:"#f92672"}},{types:["attr-name"],style:{color:"#a6e22e !important"}},{types:["doctype"],style:{color:"#8292a2"}},{types:["rule"],style:{color:"#e6db74"}}]},I={plain:{color:"#bfc7d5",backgroundColor:"#292d3e"},styles:[{types:["comment"],style:{color:"rgb(105, 112, 152)",fontStyle:"italic"}},{types:["string","inserted"],style:{color:"rgb(195, 232, 141)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation","selector"],style:{color:"rgb(199, 146, 234)"}},{types:["variable"],style:{color:"rgb(191, 199, 213)"}},{types:["class-name","attr-name"],style:{color:"rgb(255, 203, 107)"}},{types:["tag","deleted"],style:{color:"rgb(255, 85, 114)"}},{types:["operator"],style:{color:"rgb(137, 221, 255)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["keyword"],style:{fontStyle:"italic"}},{types:["doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}},{types:["url"],style:{color:"rgb(221, 221, 221)"}}]},B={plain:{color:"#9EFEFF",backgroundColor:"#2D2A55"},styles:[{types:["changed"],style:{color:"rgb(255, 238, 128)"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)"}},{types:["comment"],style:{color:"rgb(179, 98, 255)",fontStyle:"italic"}},{types:["punctuation"],style:{color:"rgb(255, 255, 255)"}},{types:["constant"],style:{color:"rgb(255, 98, 140)"}},{types:["string","url"],style:{color:"rgb(165, 255, 144)"}},{types:["variable"],style:{color:"rgb(255, 238, 128)"}},{types:["number","boolean"],style:{color:"rgb(255, 98, 140)"}},{types:["attr-name"],style:{color:"rgb(255, 180, 84)"}},{types:["keyword","operator","property","namespace","tag","selector","doctype"],style:{color:"rgb(255, 157, 0)"}},{types:["builtin","char","constant","function","class-name"],style:{color:"rgb(250, 208, 0)"}}]},z={plain:{backgroundColor:"linear-gradient(to bottom, #2a2139 75%, #34294f)",backgroundImage:"#34294f",color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"},styles:[{types:["comment","block-comment","prolog","doctype","cdata"],style:{color:"#495495",fontStyle:"italic"}},{types:["punctuation"],style:{color:"#ccc"}},{types:["tag","attr-name","namespace","number","unit","hexcode","deleted"],style:{color:"#e2777a"}},{types:["property","selector"],style:{color:"#72f1b8",textShadow:"0 0 2px #100c0f, 0 0 10px #257c5575, 0 0 35px #21272475"}},{types:["function-name"],style:{color:"#6196cc"}},{types:["boolean","selector-id","function"],style:{color:"#fdfdfd",textShadow:"0 0 2px #001716, 0 0 3px #03edf975, 0 0 5px #03edf975, 0 0 8px #03edf975"}},{types:["class-name","maybe-class-name","builtin"],style:{color:"#fff5f6",textShadow:"0 0 2px #000, 0 0 10px #fc1f2c75, 0 0 5px #fc1f2c75, 0 0 25px #fc1f2c75"}},{types:["constant","symbol"],style:{color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"}},{types:["important","atrule","keyword","selector-class"],style:{color:"#f4eee4",textShadow:"0 0 2px #393a33, 0 0 8px #f39f0575, 0 0 2px #f39f0575"}},{types:["string","char","attr-value","regex","variable"],style:{color:"#f87c32"}},{types:["parameter"],style:{fontStyle:"italic"}},{types:["entity","url"],style:{color:"#67cdcc"}},{types:["operator"],style:{color:"ffffffee"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["entity"],style:{cursor:"help"}},{types:["inserted"],style:{color:"green"}}]},$={plain:{color:"#282a2e",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(197, 200, 198)"}},{types:["string","number","builtin","variable"],style:{color:"rgb(150, 152, 150)"}},{types:["class-name","function","tag","attr-name"],style:{color:"rgb(40, 42, 46)"}}]},U={plain:{color:"#9CDCFE",backgroundColor:"#1E1E1E"},styles:[{types:["prolog"],style:{color:"rgb(0, 0, 128)"}},{types:["comment"],style:{color:"rgb(106, 153, 85)"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"rgb(86, 156, 214)"}},{types:["number","inserted"],style:{color:"rgb(181, 206, 168)"}},{types:["constant"],style:{color:"rgb(100, 102, 149)"}},{types:["attr-name","variable"],style:{color:"rgb(156, 220, 254)"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"rgb(206, 145, 120)"}},{types:["selector"],style:{color:"rgb(215, 186, 125)"}},{types:["tag"],style:{color:"rgb(78, 201, 176)"}},{types:["tag"],languages:["markup"],style:{color:"rgb(86, 156, 214)"}},{types:["punctuation","operator"],style:{color:"rgb(212, 212, 212)"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"rgb(220, 220, 170)"}},{types:["class-name"],style:{color:"rgb(78, 201, 176)"}},{types:["char"],style:{color:"rgb(209, 105, 105)"}}]},q={plain:{color:"#000000",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(0, 128, 0)"}},{types:["builtin"],style:{color:"rgb(0, 112, 193)"}},{types:["number","variable","inserted"],style:{color:"rgb(9, 134, 88)"}},{types:["operator"],style:{color:"rgb(0, 0, 0)"}},{types:["constant","char"],style:{color:"rgb(129, 31, 63)"}},{types:["tag"],style:{color:"rgb(128, 0, 0)"}},{types:["attr-name"],style:{color:"rgb(255, 0, 0)"}},{types:["deleted","string"],style:{color:"rgb(163, 21, 21)"}},{types:["changed","punctuation"],style:{color:"rgb(4, 81, 165)"}},{types:["function","keyword"],style:{color:"rgb(0, 0, 255)"}},{types:["class-name"],style:{color:"rgb(38, 127, 153)"}}]},H={plain:{color:"#f8fafc",backgroundColor:"#011627"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#569CD6"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#f8fafc"}},{types:["attr-name","variable"],style:{color:"#9CDCFE"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#cbd5e1"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#D4D4D4"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#7dd3fc"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},G={plain:{color:"#0f172a",backgroundColor:"#f1f5f9"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#0c4a6e"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#0f172a"}},{types:["attr-name","variable"],style:{color:"#0c4a6e"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#64748b"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#475569"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#0e7490"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},V={plain:{backgroundColor:"hsl(220, 13%, 18%)",color:"hsl(220, 14%, 71%)",textShadow:"0 1px rgba(0, 0, 0, 0.3)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(220, 10%, 40%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(220, 14%, 71%)"}},{types:["attr-name","class-name","maybe-class-name","boolean","constant","number","atrule"],style:{color:"hsl(29, 54%, 61%)"}},{types:["keyword"],style:{color:"hsl(286, 60%, 67%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(355, 65%, 65%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value"],style:{color:"hsl(95, 38%, 62%)"}},{types:["variable","operator","function"],style:{color:"hsl(207, 82%, 66%)"}},{types:["url"],style:{color:"hsl(187, 47%, 55%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(220, 14%, 71%)"}}]},W={plain:{backgroundColor:"hsl(230, 1%, 98%)",color:"hsl(230, 8%, 24%)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(230, 4%, 64%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(230, 8%, 24%)"}},{types:["attr-name","class-name","boolean","constant","number","atrule"],style:{color:"hsl(35, 99%, 36%)"}},{types:["keyword"],style:{color:"hsl(301, 63%, 40%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(5, 74%, 59%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value","punctuation"],style:{color:"hsl(119, 34%, 47%)"}},{types:["variable","operator","function"],style:{color:"hsl(221, 87%, 60%)"}},{types:["url"],style:{color:"hsl(198, 99%, 37%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(230, 8%, 24%)"}}]},Q={plain:{color:"#ebdbb2",backgroundColor:"#292828"},styles:[{types:["imports","class-name","maybe-class-name","constant","doctype","builtin","function"],style:{color:"#d8a657"}},{types:["property-access"],style:{color:"#7daea3"}},{types:["tag"],style:{color:"#e78a4e"}},{types:["attr-name","char","url","regex"],style:{color:"#a9b665"}},{types:["attr-value","string"],style:{color:"#89b482"}},{types:["comment","prolog","cdata","operator","inserted"],style:{color:"#a89984"}},{types:["delimiter","boolean","keyword","selector","important","atrule","property","variable","deleted"],style:{color:"#ea6962"}},{types:["entity","number","symbol"],style:{color:"#d3869b"}}]},K={plain:{color:"#654735",backgroundColor:"#f9f5d7"},styles:[{types:["delimiter","boolean","keyword","selector","important","atrule","property","variable","deleted"],style:{color:"#af2528"}},{types:["imports","class-name","maybe-class-name","constant","doctype","builtin"],style:{color:"#b4730e"}},{types:["string","attr-value"],style:{color:"#477a5b"}},{types:["property-access"],style:{color:"#266b79"}},{types:["function","attr-name","char","url"],style:{color:"#72761e"}},{types:["tag"],style:{color:"#b94c07"}},{types:["comment","prolog","cdata","operator","inserted"],style:{color:"#a89984"}},{types:["entity","number","symbol"],style:{color:"#924f79"}}]},Y=/\r\n|\r|\n/,X=e=>{0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},Z=(e,t)=>{const n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)},J=e=>{const t=[[]],n=[e],r=[0],a=[e.length];let o=0,i=0,l=[];const s=[l];for(;i>-1;){for(;(o=r[i]++)<a[i];){let e,u=t[i];const c=n[i][o];if("string"==typeof c?(u=i>0?u:["plain"],e=c):(u=Z(u,c.type),c.alias&&(u=Z(u,c.alias)),e=c.content),"string"!=typeof e){i++,t.push(u),n.push(e),r.push(0),a.push(e.length);continue}const d=e.split(Y),f=d.length;l.push({types:u,content:d[0]});for(let t=1;t<f;t++)X(l),s.push(l=[]),l.push({types:u,content:d[t]})}i--,t.pop(),n.pop(),r.pop(),a.pop()}return X(l),s},ee=(e,t)=>{const{plain:n}=e,r=e.styles.reduce(((e,n)=>{const{languages:r,style:a}=n;return r&&!r.includes(t)||n.types.forEach((t=>{const n=x(x({},e[t]),a);e[t]=n})),e}),{});return r.root=n,r.plain=_(x({},n),{backgroundColor:void 0}),r},te=({children:e,language:t,code:n,theme:r,prism:a})=>{const o=t.toLowerCase(),i=ee(r,o),l=(e=>(0,c.useCallback)((t=>{var n=t,{className:r,style:a,line:o}=n,i=E(n,["className","style","line"]);const l=_(x({},i),{className:(0,d.A)("token-line",r)});return"object"==typeof e&&"plain"in e&&(l.style=e.plain),"object"==typeof a&&(l.style=x(x({},l.style||{}),a)),l}),[e]))(i),s=(e=>{const t=(0,c.useCallback)((({types:t,empty:n})=>{if(null!=e)return 1===t.length&&"plain"===t[0]?null!=n?{display:"inline-block"}:void 0:1===t.length&&null!=n?e[t[0]]:Object.assign(null!=n?{display:"inline-block"}:{},...t.map((t=>e[t])))}),[e]);return(0,c.useCallback)((e=>{var n=e,{token:r,className:a,style:o}=n,i=E(n,["token","className","style"]);const l=_(x({},i),{className:(0,d.A)("token",...r.types,a),children:r.content,style:t(r)});return null!=o&&(l.style=x(x({},l.style||{}),o)),l}),[t])})(i),u=(({prism:e,code:t,grammar:n,language:r})=>(0,c.useMemo)((()=>{if(null==n)return J([t]);const a={code:t,grammar:n,language:r,tokens:[]};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(t,n),e.hooks.run("after-tokenize",a),J(a.tokens)}),[t,n,r,e]))({prism:a,language:o,code:n,grammar:a.languages[o]});return e({tokens:u,className:`prism-code language-${o}`,style:null!=i?i.root:{},getLineProps:l,getTokenProps:s})},ne=e=>(0,c.createElement)(te,_(x({},e),{prism:e.prism||A,theme:e.theme||U,code:e.code,language:e.language}))},2131:(e,t,n)=>{"use strict";n.d(t,{o:()=>i});var r=n(4586),a=n(6347),o=n(440);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:l}}=(0,r.A)(),{pathname:s}=(0,a.zy)(),u=(0,o.Ks)(s,{trailingSlash:n,baseUrl:e}),c=l===i?e:e.replace(`/${l}/`,"/"),d=u.replace(e,"");return{createUrl:function({locale:e,fullyQualified:n}){return`${n?t:""}${function(e){return e===i?`${c}`:`${c}${e}/`}(e)}${d}`}}}},2303:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(6125);function o(){return(0,r.useContext)(a.o)}},2566:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addPrefix=function(e,t){return e.startsWith(t)?e:`${t}${e}`},t.removeSuffix=function(e,t){if(""===t)return e;return e.endsWith(t)?e.slice(0,-t.length):e},t.addSuffix=function(e,t){return e.endsWith(t)?e:`${e}${t}`},t.removePrefix=function(e,t){return e.startsWith(t)?e.slice(t.length):e}},2654:e=>{"use strict";e.exports={}},2694:(e,t,n)=>{"use strict";var r=n(6925);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},2799:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,a=n?Symbol.for("react.portal"):60106,o=n?Symbol.for("react.fragment"):60107,i=n?Symbol.for("react.strict_mode"):60108,l=n?Symbol.for("react.profiler"):60114,s=n?Symbol.for("react.provider"):60109,u=n?Symbol.for("react.context"):60110,c=n?Symbol.for("react.async_mode"):60111,d=n?Symbol.for("react.concurrent_mode"):60111,f=n?Symbol.for("react.forward_ref"):60112,p=n?Symbol.for("react.suspense"):60113,m=n?Symbol.for("react.suspense_list"):60120,h=n?Symbol.for("react.memo"):60115,g=n?Symbol.for("react.lazy"):60116,y=n?Symbol.for("react.block"):60121,b=n?Symbol.for("react.fundamental"):60117,v=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function k(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case c:case d:case o:case l:case i:case p:return e;default:switch(e=e&&e.$$typeof){case u:case f:case g:case h:case s:return e;default:return t}}case a:return t}}}function S(e){return k(e)===d}t.AsyncMode=c,t.ConcurrentMode=d,t.ContextConsumer=u,t.ContextProvider=s,t.Element=r,t.ForwardRef=f,t.Fragment=o,t.Lazy=g,t.Memo=h,t.Portal=a,t.Profiler=l,t.StrictMode=i,t.Suspense=p,t.isAsyncMode=function(e){return S(e)||k(e)===c},t.isConcurrentMode=S,t.isContextConsumer=function(e){return k(e)===u},t.isContextProvider=function(e){return k(e)===s},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return k(e)===f},t.isFragment=function(e){return k(e)===o},t.isLazy=function(e){return k(e)===g},t.isMemo=function(e){return k(e)===h},t.isPortal=function(e){return k(e)===a},t.isProfiler=function(e){return k(e)===l},t.isStrictMode=function(e){return k(e)===i},t.isSuspense=function(e){return k(e)===p},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===o||e===d||e===l||e===i||e===p||e===m||"object"==typeof e&&null!==e&&(e.$$typeof===g||e.$$typeof===h||e.$$typeof===s||e.$$typeof===u||e.$$typeof===f||e.$$typeof===b||e.$$typeof===v||e.$$typeof===w||e.$$typeof===y)},t.typeOf=k},2831:(e,t,n)=>{"use strict";n.d(t,{u:()=>i,v:()=>l});var r=n(6347),a=n(8168),o=n(6540);function i(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var a=e.path?(0,r.B6)(t,e):n.length?n[n.length-1].match:r.Ix.computeRootMatch(t);return a&&(n.push({route:e,match:a}),e.routes&&i(e.routes,t,n)),a})),n}function l(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?o.createElement(r.dO,n,e.map((function(e,n){return o.createElement(r.qh,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,a.A)({},n,{},t,{route:e})):o.createElement(e.component,(0,a.A)({},n,t,{route:e}))}})}))):null}},2833:e=>{e.exports=function(e,t,n,r){var a=n?n.call(r,e,t):void 0;if(void 0!==a)return!!a;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var o=Object.keys(e),i=Object.keys(t);if(o.length!==i.length)return!1;for(var l=Object.prototype.hasOwnProperty.bind(t),s=0;s<o.length;s++){var u=o[s];if(!l(u))return!1;var c=e[u],d=t[u];if(!1===(a=n?n.call(r,c,d,u):void 0)||void 0===a&&c!==d)return!1}return!0}},2892:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function a(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{A:()=>a})},2983:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addTrailingSlash=a,t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[i]=e.split(/[#?]/),l="/"===i||i===r?i:(s=i,u=n,u?a(s):o(s));var s,u;return e.replace(i,l)},t.addLeadingSlash=function(e){return(0,r.addPrefix)(e,"/")},t.removeTrailingSlash=o;const r=n(2566);function a(e){return e.endsWith("/")?e:`${e}/`}function o(e){return(0,r.removeSuffix)(e,"/")}},3001:(e,t,n)=>{"use strict";n.r(t)},3025:(e,t,n)=>{"use strict";n.d(t,{n:()=>l,r:()=>s});var r=n(6540),a=n(9532),o=n(4848);const i=r.createContext(null);function l({children:e,version:t}){return(0,o.jsx)(i.Provider,{value:t,children:e})}function s(){const e=(0,r.useContext)(i);if(null===e)throw new a.dV("DocsVersionProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{W:()=>i,o:()=>o});var r=n(6540),a=n(4848);const o=r.createContext(null);function i({children:e,value:t}){const n=r.useContext(o),i=(0,r.useMemo)((()=>function({parent:e,value:t}){if(!e){if(!t)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in t))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return t}const n={...e.data,...t?.data};return{plugin:e.plugin,data:n}}({parent:n,value:t})),[n,t]);return(0,a.jsx)(o.Provider,{value:i,children:e})}},3104:(e,t,n)=>{"use strict";n.d(t,{Mq:()=>f,Tv:()=>u,gk:()=>p});var r=n(6540),a=n(8193),o=n(2303),i=(n(205),n(9532)),l=n(4848);const s=r.createContext(void 0);function u({children:e}){const t=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,l.jsx)(s.Provider,{value:t,children:e})}function c(){const e=(0,r.useContext)(s);if(null==e)throw new i.dV("ScrollControllerProvider");return e}const d=()=>a.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function f(e,t=[]){const{scrollEventsEnabledRef:n}=c(),a=(0,r.useRef)(d()),o=(0,i._q)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=d();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function p(){const e=(0,r.useRef)(null),t=(0,o.A)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&a<e)&&(t=requestAnimationFrame(r),window.scrollTo(0,Math.floor(.85*(a-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3109:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{O:()=>r})},3157:(e,t,n)=>{var r={"./":8722};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=3157},3186:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});n(6540);const r={iconExternalLink:"iconExternalLink_nPIU"};var a=n(4848);const o="#theme-svg-external-link";function i({width:e=13.5,height:t=13.5}){return(0,a.jsx)("svg",{width:e,height:t,"aria-hidden":"true",className:r.iconExternalLink,children:(0,a.jsx)("use",{href:o})})}},3259:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function a(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n(6540),s=[],u=[];var c=l.createContext(null);function d(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function f(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(r){var a=d(e[r]);a.loading?t.loading=!0:(t.loaded[r]=a.loaded,t.error=a.error),n.push(a.promise),a.promise.then((function(e){t.loaded[r]=e})).catch((function(e){t.error=e}))}))}catch(r){t.error=r}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function p(e,t){return l.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function m(e,t){var d,f;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var m=i({loader:null,loading:null,delay:200,timeout:null,render:p,webpack:null,modules:null},t),h=null;function g(){return h||(h=e(m.loader)),h.promise}return s.push(g),"function"==typeof m.webpack&&u.push((function(){if((0,m.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return g()})),f=d=function(t){function n(n){var r;return o(a(a(r=t.call(this,n)||this)),"retry",(function(){r.setState({error:null,loading:!0,timedOut:!1}),h=e(m.loader),r._loadModule()})),g(),r.state={error:h.error,pastDelay:!1,timedOut:!1,loading:h.loading,loaded:h.loaded},r}r(n,t),n.preload=function(){return g()};var i=n.prototype;return i.UNSAFE_componentWillMount=function(){this._loadModule()},i.componentDidMount=function(){this._mounted=!0},i._loadModule=function(){var e=this;if(this.context&&Array.isArray(m.modules)&&m.modules.forEach((function(t){e.context.report(t)})),h.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof m.delay&&(0===m.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),m.delay)),"number"==typeof m.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),m.timeout));var n=function(){t({error:h.error,loaded:h.loaded,loading:h.loading}),e._clearTimeouts()};h.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},i.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},i._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},i.render=function(){return this.state.loading||this.state.error?l.createElement(m.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?m.render(this.state.loaded,this.props):null},n}(l.Component),o(d,"contextType",c),f}function h(e){return m(d,e)}h.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return m(f,e)};var g=function(e){function t(){return e.apply(this,arguments)||this}return r(t,e),t.prototype.render=function(){return l.createElement(c.Provider,{value:{report:this.props.report}},l.Children.only(this.props.children))},t}(l.Component);function y(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return y(e)}))}h.Capture=g,h.preloadAll=function(){return new Promise((function(e,t){y(s).then(e,t)}))},h.preloadReady=function(){return new Promise((function(e,t){y(u).then(e,e)}))},e.exports=h},3427:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});var r=n(6540);n(4848);const a=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),o=()=>(0,r.useContext)(a);function i(){return o()}},3465:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});n(6540);var r=n(8774),a=n(6025),o=n(4586),i=n(6342),l=n(1122),s=n(4848);function u({logo:e,alt:t,imageClassName:n}){const r={light:(0,a.Ay)(e.src),dark:(0,a.Ay)(e.srcDark||e.src)},o=(0,s.jsx)(l.A,{className:e.className,sources:r,height:e.height,width:e.width,alt:t,style:e.style});return n?(0,s.jsx)("div",{className:n,children:o}):o}function c(e){const{siteConfig:{title:t}}=(0,o.A)(),{navbar:{title:n,logo:l}}=(0,i.p)(),{imageClassName:c,titleClassName:d,...f}=e,p=(0,a.Ay)(l?.href||"/"),m=n?"":t,h=l?.alt??m;return(0,s.jsxs)(r.A,{to:p,...f,...l?.target&&{target:l.target},children:[l&&(0,s.jsx)(u,{logo:l,alt:h,imageClassName:c}),null!=n&&(0,s.jsx)("b",{className:d,children:n})]})}},3886:(e,t,n)=>{"use strict";n.d(t,{VQ:()=>g,g1:()=>b});var r=n(6540),a=n(4070),o=n(7065),i=n(6342),l=n(679),s=n(9532),u=n(4848);const c=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,l.Wf)(c(e),{persistence:t}).set(n)},read:(e,t)=>(0,l.Wf)(c(e),{persistence:t}).get(),clear:(e,t)=>{(0,l.Wf)(c(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const p=r.createContext(null);function m(){const e=(0,a.Gy)(),t=(0,i.p)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,l]=(0,r.useState)((()=>f(n)));(0,r.useEffect)((()=>{l(function({pluginIds:e,versionPersistence:t,allDocsData:n}){function r(e){const r=d.read(e,t);return n[e].versions.some((e=>e.name===r))?{preferredVersionName:r}:(d.clear(e,t),{preferredVersionName:null})}return Object.fromEntries(e.map((e=>[e,r(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function h({children:e}){const t=m();return(0,u.jsx)(p.Provider,{value:t,children:e})}function g({children:e}){return(0,u.jsx)(h,{children:e})}function y(){const e=(0,r.useContext)(p);if(!e)throw new s.dV("DocsPreferredVersionContextProvider");return e}function b(e=o.W){const t=(0,a.ht)(e),[n,i]=y(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find((e=>e.name===l))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},4054:e=>{"use strict";e.exports=JSON.parse('{"/BharatMLStack/blog-170":{"__comp":"a6aa9e1f","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"f2c141e4"}],"__props":"f994c8da"},"/BharatMLStack/blog/archive-dde":{"__comp":"9e4087bc","__context":{"plugin":"36994c47"},"__props":"6479fb86"},"/BharatMLStack/blog/authors-f47":{"__comp":"621db11d","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","__props":"2d865531"},"/BharatMLStack/blog/post-one-e5f":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"09dd5be9"},"/BharatMLStack/blog/tags-8af":{"__comp":"01a85c17","__context":{"plugin":"36994c47"},"sidebar":"814f3328","__props":"7fa80e1c"},"/BharatMLStack/blog/tags/interaction-store-4b6":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"f2c141e4"}],"__props":"3980073a"},"/BharatMLStack/blog/tags/meesho-316":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"f2c141e4"}],"__props":"1a64de69"},"/BharatMLStack/blog/tags/mlplatform-48f":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"f2c141e4"}],"__props":"479eb034"},"/BharatMLStack/blog/tags/online-feature-store-44b":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"f2c141e4"}],"__props":"3e1c5046"},"/BharatMLStack/markdown-page-747":{"__comp":"1f391b9e","__context":{"plugin":"a7456010"},"content":"393be207"},"/BharatMLStack/-e34":{"__comp":"c4f5d8e4","__context":{"plugin":"a7456010"},"config":"5e9f5e1a"},"/BharatMLStack/-fd6":{"__comp":"5e95c892","__context":{"plugin":"aba21aa0"}},"/BharatMLStack/-098":{"__comp":"a7bd4aaa","__props":"4137b431"},"/BharatMLStack/-925":{"__comp":"a94703ab"},"/BharatMLStack/category/go-sdk-6b0":{"__comp":"14eb3368","__props":"c7b64fcc"},"/BharatMLStack/category/online-feature-store-7ee":{"__comp":"14eb3368","__props":"8ac6191a"},"/BharatMLStack/category/python-sdk-1fd":{"__comp":"14eb3368","__props":"44d1c015"},"/BharatMLStack/category/quick-start-dff":{"__comp":"14eb3368","__props":"14064408"},"/BharatMLStack/category/sdks-532":{"__comp":"14eb3368","__props":"616111d3"},"/BharatMLStack/category/trufflebox-ui-5f5":{"__comp":"14eb3368","__props":"fcf4f6ca"},"/BharatMLStack/category/v100-ddd":{"__comp":"14eb3368","__props":"fa31f022"},"/BharatMLStack/online-feature-store/v1.0.0-218":{"__comp":"14eb3368","__props":"72dc5b25"},"/BharatMLStack/online-feature-store/v1.0.0/architecture-0af":{"__comp":"17896441","content":"e66382f6"},"/BharatMLStack/online-feature-store/v1.0.0/benchmarks-889":{"__comp":"17896441","content":"67d4782a"},"/BharatMLStack/online-feature-store/v1.0.0/data-formats-46e":{"__comp":"17896441","content":"4caa95bf"},"/BharatMLStack/online-feature-store/v1.0.0/functionalities-415":{"__comp":"17896441","content":"c4822c4f"},"/BharatMLStack/online-feature-store/v1.0.0/release-notes-36c":{"__comp":"17896441","content":"d152284c"},"/BharatMLStack/quick-start/v1.0.0/quick-start-b19":{"__comp":"17896441","content":"0fff8dc8"},"/BharatMLStack/sdks/go/v1.0.0/feature_client-1df":{"__comp":"17896441","content":"4af50aac"},"/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client-9dc":{"__comp":"17896441","content":"0413d9af"},"/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client-1bc":{"__comp":"17896441","content":"ac51638e"},"/BharatMLStack/trufflebox-ui/v1.0.0/userguide-65e":{"__comp":"17896441","content":"176d210f"}}')},4070:(e,t,n)=>{"use strict";n.d(t,{zK:()=>h,vT:()=>f,Gy:()=>c,HW:()=>g,ht:()=>d,r7:()=>m,jh:()=>p});var r=n(6347),a=n(4586),o=n(7065);function i(e,t={}){const n=function(){const{globalData:e}=(0,a.A)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find((e=>e.isLast));function s(e,t){const n=function(e,t){return[...e.versions].sort(((e,t)=>e.path===t.path?0:e.path.includes(t.path)?-1:t.path.includes(e.path)?1:0)).find((e=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),a=n?.docs.find((e=>!!(0,r.B6)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const u={},c=()=>i("docusaurus-plugin-content-docs")??u,d=e=>{try{return function(e,t=o.W,n={}){const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0})}catch(t){throw new Error("You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled"+("Default"===e?"":` (pluginId=${e}`),{cause:t})}};function f(e={}){const t=c(),{pathname:n}=(0,r.zy)();return function(e,t,n={}){const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((([,e])=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1}))),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function p(e){return d(e).versions}function m(e){const t=d(e);return l(t)}function h(e){const t=d(e),{pathname:n}=(0,r.zy)();return s(t,n)}function g(e){const t=d(e),{pathname:n}=(0,r.zy)();return function(e,t){const n=l(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},4090:(e,t,n)=>{"use strict";n.d(t,{w:()=>a,J:()=>o});var r=n(6540);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},4146:(e,t,n)=>{"use strict";var r=n(4363),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||a}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var u=Object.defineProperty,c=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var a=p(n);a&&a!==m&&e(t,a,r)}var i=c(n);d&&(i=i.concat(d(n)));for(var l=s(t),h=s(n),g=0;g<i.length;++g){var y=i[g];if(!(o[y]||r&&r[y]||h&&h[y]||l&&l[y])){var b=f(n,y);try{u(t,y,b)}catch(v){}}}}return t}},4164:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(n=r(e[t]))&&(a&&(a+=" "),a+=n)}else for(n in e)e[n]&&(a&&(a+=" "),a+=n);return a}n.d(t,{A:()=>a});const a=function(){for(var e,t,n=0,a="",o=arguments.length;n<o;n++)(e=arguments[n])&&(t=r(e))&&(a&&(a+=" "),a+=t);return a}},4363:(e,t,n)=>{"use strict";e.exports=n(2799)},4477:(e,t)=>{"use strict";function n(e,t){var n=e.length;e.push(t);e:for(;0<n;){var r=n-1>>>1,a=e[r];if(!(0<o(a,t)))break e;e[r]=t,e[n]=a,n=r}}function r(e){return 0===e.length?null:e[0]}function a(e){if(0===e.length)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,a=e.length,i=a>>>1;r<i;){var l=2*(r+1)-1,s=e[l],u=l+1,c=e[u];if(0>o(s,n))u<a&&0>o(c,s)?(e[r]=c,e[u]=n,r=u):(e[r]=s,e[l]=n,r=l);else{if(!(u<a&&0>o(c,n)))break e;e[r]=c,e[u]=n,r=u}}}return t}function o(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}if(t.unstable_now=void 0,"object"==typeof performance&&"function"==typeof performance.now){var i=performance;t.unstable_now=function(){return i.now()}}else{var l=Date,s=l.now();t.unstable_now=function(){return l.now()-s}}var u=[],c=[],d=1,f=null,p=3,m=!1,h=!1,g=!1,y=!1,b="function"==typeof setTimeout?setTimeout:null,v="function"==typeof clearTimeout?clearTimeout:null,w="undefined"!=typeof setImmediate?setImmediate:null;function k(e){for(var t=r(c);null!==t;){if(null===t.callback)a(c);else{if(!(t.startTime<=e))break;a(c),t.sortIndex=t.expirationTime,n(u,t)}t=r(c)}}function S(e){if(g=!1,k(e),!h)if(null!==r(u))h=!0,_||(_=!0,x());else{var t=r(c);null!==t&&N(S,t.startTime-e)}}var x,_=!1,E=-1,C=5,A=-1;function T(){return!!y||!(t.unstable_now()-A<C)}function L(){if(y=!1,_){var e=t.unstable_now();A=e;var n=!0;try{e:{h=!1,g&&(g=!1,v(E),E=-1),m=!0;var o=p;try{t:{for(k(e),f=r(u);null!==f&&!(f.expirationTime>e&&T());){var i=f.callback;if("function"==typeof i){f.callback=null,p=f.priorityLevel;var l=i(f.expirationTime<=e);if(e=t.unstable_now(),"function"==typeof l){f.callback=l,k(e),n=!0;break t}f===r(u)&&a(u),k(e)}else a(u);f=r(u)}if(null!==f)n=!0;else{var s=r(c);null!==s&&N(S,s.startTime-e),n=!1}}break e}finally{f=null,p=o,m=!1}n=void 0}}finally{n?x():_=!1}}}if("function"==typeof w)x=function(){w(L)};else if("undefined"!=typeof MessageChannel){var j=new MessageChannel,P=j.port2;j.port1.onmessage=L,x=function(){P.postMessage(null)}}else x=function(){b(L,0)};function N(e,n){E=b((function(){e(t.unstable_now())}),n)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):C=0<e?Math.floor(1e3/e):5},t.unstable_getCurrentPriorityLevel=function(){return p},t.unstable_next=function(e){switch(p){case 1:case 2:case 3:var t=3;break;default:t=p}var n=p;p=t;try{return e()}finally{p=n}},t.unstable_requestPaint=function(){y=!0},t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=p;p=e;try{return t()}finally{p=n}},t.unstable_scheduleCallback=function(e,a,o){var i=t.unstable_now();switch("object"==typeof o&&null!==o?o="number"==typeof(o=o.delay)&&0<o?i+o:i:o=i,e){case 1:var l=-1;break;case 2:l=250;break;case 5:l=1073741823;break;case 4:l=1e4;break;default:l=5e3}return e={id:d++,callback:a,priorityLevel:e,startTime:o,expirationTime:l=o+l,sortIndex:-1},o>i?(e.sortIndex=o,n(c,e),null===r(u)&&e===r(c)&&(g?(v(E),E=-1):g=!0,N(S,o-i))):(e.sortIndex=l,n(u,e),h||m||(h=!0,_||(_=!0,x()))),e},t.unstable_shouldYield=T,t.unstable_wrapCallback=function(e){var t=p;return function(){var n=p;p=t;try{return e.apply(this,arguments)}finally{p=n}}}},4563:(e,t,n)=>{"use strict";n.d(t,{AL:()=>c,s$:()=>d});var r=n(6540),a=n(4586),o=n(6803),i=n(9532),l=n(4848);const s=({title:e,siteTitle:t,titleDelimiter:n})=>{const r=e?.trim();return r&&r!==t?`${r} ${n} ${t}`:t},u=(0,r.createContext)(null);function c({formatter:e,children:t}){return(0,l.jsx)(u.Provider,{value:e,children:t})}function d(){const e=function(){const e=(0,r.useContext)(u);if(null===e)throw new i.dV("TitleFormatterProvider");return e}(),{siteConfig:t}=(0,a.A)(),{title:n,titleDelimiter:l}=t,{plugin:c}=(0,o.A)();return{format:t=>e({title:t,siteTitle:n,titleDelimiter:l,plugin:c,defaultFormatter:s})}}},4581:(e,t,n)=>{"use strict";n.d(t,{l:()=>l});var r=n(6540),a=n(8193);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l({desktopBreakpoint:e=i}={}){const[t,n]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function t(){n(function(e){if(!a.A.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?o.desktop:o.mobile}(e))}return t(),window.addEventListener("resize",t),()=>{window.removeEventListener("resize",t)}}),[e]),t}},4586:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(6988);function o(){return(0,r.useContext)(a.o)}},4625:(e,t,n)=>{"use strict";n.d(t,{I9:()=>d,Kd:()=>c,N_:()=>y,k2:()=>w});var r=n(6347),a=n(2892),o=n(6540),i=n(1513),l=n(8168),s=n(8587),u=n(1561),c=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,i.zR)(t.props),t}return(0,a.A)(t,e),t.prototype.render=function(){return o.createElement(r.Ix,{history:this.history,children:this.props.children})},t}(o.Component);var d=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,i.TM)(t.props),t}return(0,a.A)(t,e),t.prototype.render=function(){return o.createElement(r.Ix,{history:this.history,children:this.props.children})},t}(o.Component);var f=function(e,t){return"function"==typeof e?e(t):e},p=function(e,t){return"string"==typeof e?(0,i.yJ)(e,null,null,t):e},m=function(e){return e},h=o.forwardRef;void 0===h&&(h=m);var g=h((function(e,t){var n=e.innerRef,r=e.navigate,a=e.onClick,i=(0,s.A)(e,["innerRef","navigate","onClick"]),u=i.target,c=(0,l.A)({},i,{onClick:function(e){try{a&&a(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||u&&"_self"!==u||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),r())}});return c.ref=m!==h&&t||n,o.createElement("a",c)}));var y=h((function(e,t){var n=e.component,a=void 0===n?g:n,c=e.replace,d=e.to,y=e.innerRef,b=(0,s.A)(e,["component","replace","to","innerRef"]);return o.createElement(r.XZ.Consumer,null,(function(e){e||(0,u.A)(!1);var n=e.history,r=p(f(d,e.location),e.location),s=r?n.createHref(r):"",g=(0,l.A)({},b,{href:s,navigate:function(){var t=f(d,e.location),r=(0,i.AO)(e.location)===(0,i.AO)(p(t));(c||r?n.replace:n.push)(t)}});return m!==h?g.ref=t||y:g.innerRef=y,o.createElement(a,g)}))})),b=function(e){return e},v=o.forwardRef;void 0===v&&(v=b);var w=v((function(e,t){var n=e["aria-current"],a=void 0===n?"page":n,i=e.activeClassName,c=void 0===i?"active":i,d=e.activeStyle,m=e.className,h=e.exact,g=e.isActive,w=e.location,k=e.sensitive,S=e.strict,x=e.style,_=e.to,E=e.innerRef,C=(0,s.A)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return o.createElement(r.XZ.Consumer,null,(function(e){e||(0,u.A)(!1);var n=w||e.location,i=p(f(_,n),n),s=i.pathname,A=s&&s.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),T=A?(0,r.B6)(n.pathname,{path:A,exact:h,sensitive:k,strict:S}):null,L=!!(g?g(T,n):T),j="function"==typeof m?m(L):m,P="function"==typeof x?x(L):x;L&&(j=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(j,c),P=(0,l.A)({},P,d));var N=(0,l.A)({"aria-current":L&&a||null,className:j,style:P,to:i},C);return b!==v?N.ref=t||E:N.innerRef=E,o.createElement(y,N)}))}))},4634:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},4784:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={title:"BharatMLStack",tagline:"BharatMLStack is a comprehensive, production-ready machine learning infrastructure platform designed to democratize ML capabilities across India and beyond. Our mission is to provide a robust, scalable, and accessible ML stack that empowers organizations to build, deploy, and manage machine learning solutions at massive scale.",favicon:"img/favicon.ico",future:{v4:{removeLegacyPostBuildHeadAttribute:!0,useCssCascadeLayers:!0},experimental_faster:{swcJsLoader:!1,swcJsMinimizer:!1,swcHtmlMinimizer:!1,lightningCssMinimizer:!1,mdxCrossCompilerCache:!1,rspackBundler:!1,rspackPersistentCache:!1,ssgWorkerThreads:!1},experimental_storage:{type:"localStorage",namespace:!1},experimental_router:"browser"},url:"https://meesho.github.io",baseUrl:"/BharatMLStack/",organizationName:"Meesho Ltd.",projectName:"BharatMLStack",onBrokenLinks:"throw",onBrokenMarkdownLinks:"warn",i18n:{defaultLocale:"en",locales:["en"],path:"i18n",localeConfigs:{}},presets:[["classic",{docs:{sidebarPath:"./sidebars.js",editUrl:"https://github.com/Meesho/BharatMLStack/tree/main/docs",routeBasePath:"/"},blog:{showReadingTime:!0,feedOptions:{type:["rss","atom"],xslt:!0},editUrl:"https://github.com/Meesho/BharatMLStack/tree/main/docs",onInlineTags:"warn",onInlineAuthors:"warn",onUntruncatedBlogPosts:"warn"},theme:{customCss:"./src/css/custom.css"}}]],themeConfig:{image:"img/docusaurus-social-card.jpg",navbar:{title:"BharatMLStack",items:[{type:"docSidebar",sidebarId:"tutorialSidebar",position:"left",label:"Docs"},{to:"/blog",label:"Blog",position:"left"},{href:"https://github.com/Meesho/BharatMLStack",label:"GitHub",position:"right"}],hideOnScroll:!1},footer:{style:"dark",links:[{title:"Community",items:[{label:"Github Discussions",href:"https://github.com/Meesho/BharatMLStack/discussions"},{label:"Discord",href:"https://discord.gg/XkT7XsV2AU"}]},{title:"More",items:[{label:"Blog",to:"/blog"},{label:"GitHub",href:"https://github.com/Meesho/BharatMLStack"}]}],copyright:"Copyright \xa9 2025 Meesho Ltd. Built with Docusaurus."},prism:{theme:{plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:[],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},colorMode:{defaultMode:"light",disableSwitch:!1,respectPrefersColorScheme:!1},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},blog:{sidebar:{groupByYear:!0}},metadata:[],tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3}},baseUrlIssueBanner:!0,onBrokenAnchors:"warn",onDuplicateRoutes:"warn",staticDirectories:["static"],customFields:{},plugins:[],themes:[],scripts:[],headTags:[],stylesheets:[],clientModules:[],titleDelimiter:"|",noIndex:!1,markdown:{format:"mdx",mermaid:!1,mdx1Compat:{comments:!0,admonitions:!0,headingIds:!0},anchors:{maintainCase:!1}}}},4848:(e,t,n)=>{"use strict";e.exports=n(9698)},5041:(e,t,n)=>{"use strict";n.d(t,{M:()=>h,o:()=>m});var r=n(6540),a=n(2303),o=n(679),i=n(9532),l=n(6342),s=n(4848);const u=(0,o.Wf)("docusaurus.announcement.dismiss"),c=(0,o.Wf)("docusaurus.announcement.id"),d=()=>"true"===u.get(),f=e=>u.set(String(e)),p=r.createContext(null);function m({children:e}){const t=function(){const{announcementBar:e}=(0,l.p)(),t=(0,a.A)(),[n,o]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{o(d())}),[]);const i=(0,r.useCallback)((()=>{f(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=c.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;c.set(t),r&&f(!1),!r&&d()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,s.jsx)(p.Provider,{value:t,children:e})}function h(){const e=(0,r.useContext)(p);if(!e)throw new i.dV("AnnouncementBarProvider");return e}},5062:(e,t,n)=>{"use strict";n.d(t,{$:()=>i});var r=n(6540),a=n(6347),o=n(9532);function i(e){const t=(0,a.zy)(),n=(0,o.ZC)(t),i=(0,o._q)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},5260:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});n(6540);var r=n(545),a=n(4848);function o(e){return(0,a.jsx)(r.mg,{...e})}},5293:(e,t,n)=>{"use strict";n.d(t,{G:()=>w,a:()=>v});var r=n(6540),a=n(9532),o=n(679),i=n(6342),l=n(4848);function s(){return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function u(e){return function(e,t){const n=window.matchMedia(e);return n.addEventListener("change",t),()=>n.removeEventListener("change",t)}("(prefers-color-scheme: dark)",(()=>e(s())))}const c=r.createContext(void 0),d=(0,o.Wf)("theme"),f="system",p=e=>"dark"===e?"dark":"light",m=e=>null===e||e===f?null:p(e),h={get:()=>p(document.documentElement.getAttribute("data-theme")),set:e=>{document.documentElement.setAttribute("data-theme",p(e))}},g={get:()=>m(document.documentElement.getAttribute("data-theme-choice")),set:e=>{document.documentElement.setAttribute("data-theme-choice",m(e)??f)}},y=e=>{null===e?d.del():d.set(p(e))};function b(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,i.p)(),{colorMode:a,setColorModeState:o,colorModeChoice:l,setColorModeChoiceState:c}=function(){const{colorMode:{defaultMode:e}}=(0,i.p)(),[t,n]=(0,r.useState)(e),[a,o]=(0,r.useState)(null);return(0,r.useEffect)((()=>{n(h.get()),o(g.get())}),[]),{colorMode:t,setColorModeState:n,colorModeChoice:a,setColorModeChoiceState:o}}();(0,r.useEffect)((()=>{t&&d.del()}),[t]);const f=(0,r.useCallback)(((t,r={})=>{const{persist:a=!0}=r;if(null===t){const t=n?s():e;h.set(t),o(t),g.set(null),c(null)}else h.set(t),g.set(t),o(t),c(t);a&&y(t)}),[o,c,n,e]);return(0,r.useEffect)((()=>d.listen((e=>{f(m(e.newValue))}))),[f]),(0,r.useEffect)((()=>{if(null===l&&n)return u((e=>{o(e),h.set(e)}))}),[n,l,o]),(0,r.useMemo)((()=>({colorMode:a,colorModeChoice:l,setColorMode:f,get isDarkTheme(){return"dark"===a},setLightTheme(){f("light")},setDarkTheme(){f("dark")}})),[a,l,f])}function v({children:e}){const t=b();return(0,l.jsx)(c.Provider,{value:t,children:e})}function w(){const e=(0,r.useContext)(c);if(null==e)throw new a.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},5302:(e,t,n)=>{var r=n(4634);e.exports=m,e.exports.parse=o,e.exports.compile=function(e,t){return s(o(e,t),t)},e.exports.tokensToFunction=s,e.exports.tokensToRegExp=p;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,l=0,s="",u=t&&t.delimiter||"/";null!=(n=a.exec(e));){var d=n[0],f=n[1],p=n.index;if(s+=e.slice(l,p),l=p+d.length,f)s+=f[1];else{var m=e[l],h=n[2],g=n[3],y=n[4],b=n[5],v=n[6],w=n[7];s&&(r.push(s),s="");var k=null!=h&&null!=m&&m!==h,S="+"===v||"*"===v,x="?"===v||"*"===v,_=h||u,E=y||b,C=h||("string"==typeof r[r.length-1]?r[r.length-1]:"");r.push({name:g||o++,prefix:h||"",delimiter:_,optional:x,repeat:S,partial:k,asterisk:!!w,pattern:E?c(E):w?".*":i(_,C)})}}return l<e.length&&(s+=e.substr(l)),s&&r.push(s),r}function i(e,t){return!t||t.indexOf(e)>-1?"[^"+u(e)+"]+?":u(t)+"|(?:(?!"+u(t)+")[^"+u(e)+"])+?"}function l(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function s(e,t){for(var n=new Array(e.length),a=0;a<e.length;a++)"object"==typeof e[a]&&(n[a]=new RegExp("^(?:"+e[a].pattern+")$",f(t)));return function(t,a){for(var o="",i=t||{},s=(a||{}).pretty?l:encodeURIComponent,u=0;u<e.length;u++){var c=e[u];if("string"!=typeof c){var d,f=i[c.name];if(null==f){if(c.optional){c.partial&&(o+=c.prefix);continue}throw new TypeError('Expected "'+c.name+'" to be defined')}if(r(f)){if(!c.repeat)throw new TypeError('Expected "'+c.name+'" to not repeat, but received `'+JSON.stringify(f)+"`");if(0===f.length){if(c.optional)continue;throw new TypeError('Expected "'+c.name+'" to not be empty')}for(var p=0;p<f.length;p++){if(d=s(f[p]),!n[u].test(d))throw new TypeError('Expected all "'+c.name+'" to match "'+c.pattern+'", but received `'+JSON.stringify(d)+"`");o+=(0===p?c.prefix:c.delimiter)+d}}else{if(d=c.asterisk?encodeURI(f).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):s(f),!n[u].test(d))throw new TypeError('Expected "'+c.name+'" to match "'+c.pattern+'", but received "'+d+'"');o+=c.prefix+d}}else o+=c}return o}}function u(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function c(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function d(e,t){return e.keys=t,e}function f(e){return e&&e.sensitive?"":"i"}function p(e,t,n){r(t)||(n=t||n,t=[]);for(var a=(n=n||{}).strict,o=!1!==n.end,i="",l=0;l<e.length;l++){var s=e[l];if("string"==typeof s)i+=u(s);else{var c=u(s.prefix),p="(?:"+s.pattern+")";t.push(s),s.repeat&&(p+="(?:"+c+p+")*"),i+=p=s.optional?s.partial?c+"("+p+")?":"(?:"+c+"("+p+"))?":c+"("+p+")"}}var m=u(n.delimiter||"/"),h=i.slice(-m.length)===m;return a||(i=(h?i.slice(0,-m.length):i)+"(?:"+m+"(?=$))?"),i+=o?"$":a&&h?"":"(?="+m+"|$)",d(new RegExp("^"+i,f(n)),t)}function m(e,t,n){return r(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r<n.length;r++)t.push({name:r,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return d(e,t)}(e,t):r(e)?function(e,t,n){for(var r=[],a=0;a<e.length;a++)r.push(m(e[a],t,n).source);return d(new RegExp("(?:"+r.join("|")+")",f(n)),t)}(e,t,n):function(e,t,n){return p(o(e,n),t,n)}(e,t,n)}},5338:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(1247)},5500:(e,t,n)=>{"use strict";n.d(t,{Jx:()=>y,be:()=>m,e3:()=>g});var r=n(6540),a=n(4164),o=n(5260),i=n(6803),l=n(6025),s=n(4563),u=n(4848);function c({title:e}){const t=(0,s.s$)().format(e);return(0,u.jsxs)(o.A,{children:[(0,u.jsx)("title",{children:t}),(0,u.jsx)("meta",{property:"og:title",content:t})]})}function d({description:e}){return(0,u.jsxs)(o.A,{children:[(0,u.jsx)("meta",{name:"description",content:e}),(0,u.jsx)("meta",{property:"og:description",content:e})]})}function f({image:e}){const{withBaseUrl:t}=(0,l.hH)(),n=t(e,{absolute:!0});return(0,u.jsxs)(o.A,{children:[(0,u.jsx)("meta",{property:"og:image",content:n}),(0,u.jsx)("meta",{name:"twitter:image",content:n})]})}function p({keywords:e}){return(0,u.jsx)(o.A,{children:(0,u.jsx)("meta",{name:"keywords",content:Array.isArray(e)?e.join(","):e})})}function m({title:e,description:t,keywords:n,image:r,children:a}){return(0,u.jsxs)(u.Fragment,{children:[e&&(0,u.jsx)(c,{title:e}),t&&(0,u.jsx)(d,{description:t}),n&&(0,u.jsx)(p,{keywords:n}),r&&(0,u.jsx)(f,{image:r}),a&&(0,u.jsx)(o.A,{children:a})]})}const h=r.createContext(void 0);function g({className:e,children:t}){const n=r.useContext(h),i=(0,a.A)(n,e);return(0,u.jsxs)(h.Provider,{value:i,children:[(0,u.jsx)(o.A,{children:(0,u.jsx)("html",{className:i})}),t]})}function y({children:e}){const t=(0,i.A)(),n=`plugin-${t.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const r=`plugin-id-${t.plugin.id}`;return(0,u.jsx)(g,{className:(0,a.A)(n,r),children:e})}},5556:(e,t,n)=>{e.exports=n(2694)()},5600:(e,t,n)=>{"use strict";n.d(t,{GX:()=>u,YL:()=>s,y_:()=>l});var r=n(6540),a=n(9532),o=n(4848);const i=r.createContext(null);function l({children:e}){const t=(0,r.useState)({component:null,props:null});return(0,o.jsx)(i.Provider,{value:t,children:e})}function s(){const e=(0,r.useContext)(i);if(!e)throw new a.dV("NavbarSecondaryMenuContentProvider");return e[0]}function u({component:e,props:t}){const n=(0,r.useContext)(i);if(!n)throw new a.dV("NavbarSecondaryMenuContentProvider");const[,o]=n,l=(0,a.Be)(t);return(0,r.useEffect)((()=>{o({component:e,props:l})}),[o,e,l]),(0,r.useEffect)((()=>()=>o({component:null,props:null})),[o]),null}},5947:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function a(e,t,n){return e<t?t:e>n?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),u=o.querySelector(r.barSelector),c=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(u,i(e,c,d)),1===e?(s(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){s(o,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),c)}),c)):setTimeout(t,c)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0===--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");c(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),u=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&p(a),u!=document.body&&c(u,"nprogress-custom-parent"),u.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function u(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=f(e),r=n+t;u(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);u(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},6025:(e,t,n)=>{"use strict";n.d(t,{Ay:()=>l,hH:()=>i});var r=n(6540),a=n(4586),o=n(6654);function i(){const{siteConfig:e}=(0,a.A)(),{baseUrl:t,url:n}=e,i=e.future.experimental_router,l=(0,r.useCallback)(((e,r)=>function({siteUrl:e,baseUrl:t,url:n,options:{forcePrependBaseUrl:r=!1,absolute:a=!1}={},router:i}){if(!n||n.startsWith("#")||(0,o.z)(n))return n;if("hash"===i)return n.startsWith("/")?`.${n}`:`./${n}`;if(r)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const l=n.startsWith(t)?n:t+n.replace(/^\//,"");return a?e+l:l}({siteUrl:n,baseUrl:t,url:e,options:r,router:i})),[n,t,i]);return{withBaseUrl:l}}function l(e,t={}){const{withBaseUrl:n}=i();return n(e,t)}},6125:(e,t,n)=>{"use strict";n.d(t,{o:()=>o,x:()=>i});var r=n(6540),a=n(4848);const o=r.createContext(!1);function i({children:e}){const[t,n]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{n(!0)}),[]),(0,a.jsx)(o.Provider,{value:t,children:e})}},6134:(e,t,n)=>{"use strict";var r=n(1765),a=n(4784);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t,o=globalThis.Prism;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(9700),n(8692)(`./prism-${e}`)})),delete globalThis.Prism,void 0!==o&&(globalThis.Prism=e)}(r.My)},6221:(e,t,n)=>{"use strict";var r=n(6540);function a(e){var t="https://react.dev/errors/"+e;if(1<arguments.length){t+="?args[]="+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n])}return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}function o(){}var i={d:{f:o,r:function(){throw Error(a(522))},D:o,C:o,L:o,m:o,X:o,S:o,M:o},p:0,findDOMNode:null},l=Symbol.for("react.portal");var s=r.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function u(e,t){return"font"===e?"":"string"==typeof t?"use-credentials"===t?t:"":void 0}t.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=i,t.createPortal=function(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!t||1!==t.nodeType&&9!==t.nodeType&&11!==t.nodeType)throw Error(a(299));return function(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:l,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}(e,t,null,n)},t.flushSync=function(e){var t=s.T,n=i.p;try{if(s.T=null,i.p=2,e)return e()}finally{s.T=t,i.p=n,i.d.f()}},t.preconnect=function(e,t){"string"==typeof e&&(t?t="string"==typeof(t=t.crossOrigin)?"use-credentials"===t?t:"":void 0:t=null,i.d.C(e,t))},t.prefetchDNS=function(e){"string"==typeof e&&i.d.D(e)},t.preinit=function(e,t){if("string"==typeof e&&t&&"string"==typeof t.as){var n=t.as,r=u(n,t.crossOrigin),a="string"==typeof t.integrity?t.integrity:void 0,o="string"==typeof t.fetchPriority?t.fetchPriority:void 0;"style"===n?i.d.S(e,"string"==typeof t.precedence?t.precedence:void 0,{crossOrigin:r,integrity:a,fetchPriority:o}):"script"===n&&i.d.X(e,{crossOrigin:r,integrity:a,fetchPriority:o,nonce:"string"==typeof t.nonce?t.nonce:void 0})}},t.preinitModule=function(e,t){if("string"==typeof e)if("object"==typeof t&&null!==t){if(null==t.as||"script"===t.as){var n=u(t.as,t.crossOrigin);i.d.M(e,{crossOrigin:n,integrity:"string"==typeof t.integrity?t.integrity:void 0,nonce:"string"==typeof t.nonce?t.nonce:void 0})}}else null==t&&i.d.M(e)},t.preload=function(e,t){if("string"==typeof e&&"object"==typeof t&&null!==t&&"string"==typeof t.as){var n=t.as,r=u(n,t.crossOrigin);i.d.L(e,n,{crossOrigin:r,integrity:"string"==typeof t.integrity?t.integrity:void 0,nonce:"string"==typeof t.nonce?t.nonce:void 0,type:"string"==typeof t.type?t.type:void 0,fetchPriority:"string"==typeof t.fetchPriority?t.fetchPriority:void 0,referrerPolicy:"string"==typeof t.referrerPolicy?t.referrerPolicy:void 0,imageSrcSet:"string"==typeof t.imageSrcSet?t.imageSrcSet:void 0,imageSizes:"string"==typeof t.imageSizes?t.imageSizes:void 0,media:"string"==typeof t.media?t.media:void 0})}},t.preloadModule=function(e,t){if("string"==typeof e)if(t){var n=u(t.as,t.crossOrigin);i.d.m(e,{as:"string"==typeof t.as&&"script"!==t.as?t.as:void 0,crossOrigin:n,integrity:"string"==typeof t.integrity?t.integrity:void 0})}else i.d.m(e)},t.requestFormReset=function(e){i.d.r(e)},t.unstable_batchedUpdates=function(e,t){return e(t)},t.useFormState=function(e,t,n){return s.H.useFormState(e,t,n)},t.useFormStatus=function(){return s.H.useHostTransitionStatus()},t.version="19.1.0"},6294:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(5947),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate({location:e,previousLocation:t}){if(t&&e.pathname!==t.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},6342:(e,t,n)=>{"use strict";n.d(t,{p:()=>a});var r=n(4586);function a(){return(0,r.A)().siteConfig.themeConfig}},6347:(e,t,n)=>{"use strict";n.d(t,{B6:()=>x,Ix:()=>v,W6:()=>N,XZ:()=>b,dO:()=>j,qh:()=>_,zy:()=>O});var r=n(2892),a=n(6540),o=n(5556),i=n.n(o),l=n(1513),s=n(1561),u=n(8168),c=n(5302),d=n.n(c),f=(n(4363),n(8587)),p=(n(4146),1073741823),m="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};var h=a.createContext||function(e,t){var n,o,l="__create-react-context-"+function(){var e="__global_unique_id__";return m[e]=(m[e]||0)+1}()+"__",s=function(e){function n(){for(var t,n,r,a=arguments.length,o=new Array(a),i=0;i<a;i++)o[i]=arguments[i];return(t=e.call.apply(e,[this].concat(o))||this).emitter=(n=t.props.value,r=[],{on:function(e){r.push(e)},off:function(e){r=r.filter((function(t){return t!==e}))},get:function(){return n},set:function(e,t){n=e,r.forEach((function(e){return e(n,t)}))}}),t}(0,r.A)(n,e);var a=n.prototype;return a.getChildContext=function(){var e;return(e={})[l]=this.emitter,e},a.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,a=e.value;((o=r)===(i=a)?0!==o||1/o==1/i:o!=o&&i!=i)?n=0:(n="function"==typeof t?t(r,a):p,0!==(n|=0)&&this.emitter.set(e.value,n))}var o,i},a.render=function(){return this.props.children},n}(a.Component);s.childContextTypes=((n={})[l]=i().object.isRequired,n);var u=function(t){function n(){for(var e,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(e=t.call.apply(t,[this].concat(r))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){0!==((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}(0,r.A)(n,t);var a=n.prototype;return a.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?p:t},a.componentDidMount=function(){this.context[l]&&this.context[l].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?p:e},a.componentWillUnmount=function(){this.context[l]&&this.context[l].off(this.onUpdate)},a.getValue=function(){return this.context[l]?this.context[l].get():e},a.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(a.Component);return u.contextTypes=((o={})[l]=i().object,o),{Provider:s,Consumer:u}},g=function(e){var t=h();return t.displayName=e,t},y=g("Router-History"),b=g("Router"),v=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,r.A)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return a.createElement(b.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},a.createElement(y.Provider,{children:this.props.children||null,value:this.props.history}))},t}(a.Component);a.Component;a.Component;var w={},k=1e4,S=0;function x(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,a=n.exact,o=void 0!==a&&a,i=n.strict,l=void 0!==i&&i,s=n.sensitive,u=void 0!==s&&s;return[].concat(r).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=w[n]||(w[n]={});if(r[e])return r[e];var a=[],o={regexp:d()(e,a,t),keys:a};return S<k&&(r[e]=o,S++),o}(n,{end:o,strict:l,sensitive:u}),a=r.regexp,i=r.keys,s=a.exec(e);if(!s)return null;var c=s[0],f=s.slice(1),p=e===c;return o&&!p?null:{path:n,url:"/"===n&&""===c?"/":c,isExact:p,params:i.reduce((function(e,t,n){return e[t.name]=f[n],e}),{})}}),null)}var _=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.A)(t,e),t.prototype.render=function(){var e=this;return a.createElement(b.Consumer,null,(function(t){t||(0,s.A)(!1);var n=e.props.location||t.location,r=e.props.computedMatch?e.props.computedMatch:e.props.path?x(n.pathname,e.props):t.match,o=(0,u.A)({},t,{location:n,match:r}),i=e.props,l=i.children,c=i.component,d=i.render;return Array.isArray(l)&&function(e){return 0===a.Children.count(e)}(l)&&(l=null),a.createElement(b.Provider,{value:o},o.match?l?"function"==typeof l?l(o):l:c?a.createElement(c,o):d?d(o):null:"function"==typeof l?l(o):null)}))},t}(a.Component);function E(e){return"/"===e.charAt(0)?e:"/"+e}function C(e,t){if(!e)return t;var n=E(e);return 0!==t.pathname.indexOf(n)?t:(0,u.A)({},t,{pathname:t.pathname.substr(n.length)})}function A(e){return"string"==typeof e?e:(0,l.AO)(e)}function T(e){return function(){(0,s.A)(!1)}}function L(){}a.Component;var j=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.A)(t,e),t.prototype.render=function(){var e=this;return a.createElement(b.Consumer,null,(function(t){t||(0,s.A)(!1);var n,r,o=e.props.location||t.location;return a.Children.forEach(e.props.children,(function(e){if(null==r&&a.isValidElement(e)){n=e;var i=e.props.path||e.props.from;r=i?x(o.pathname,(0,u.A)({},e.props,{path:i})):t.match}})),r?a.cloneElement(n,{location:o,computedMatch:r}):null}))},t}(a.Component);var P=a.useContext;function N(){return P(y)}function O(){return P(b).location}},6540:(e,t,n)=>{"use strict";e.exports=n(9869)},6654:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{A:()=>a,z:()=>r})},6803:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(3102);function o(){const e=r.useContext(a.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}},6921:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((([n,o])=>{const i=a?`${a}.${n}`:n;r(o)?e(o,i):t[i]=o}))}(e),t}},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},6969:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to <a href="https://webplatform.github.io/docs/">WebPlatform.org documentation</a>. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (<code>.comment</code> can become <code>.namespace--comment</code>) or replace them with your defined ones (like <code>.editor__comment</code>). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the <code>highlightAll</code> and <code>highlightAllUnder</code> methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},6972:(e,t,n)=>{"use strict";n.d(t,{$S:()=>m,B5:()=>C,Nr:()=>p,OF:()=>S,QB:()=>E,Vd:()=>x,Y:()=>w,a4:()=>h,cC:()=>f,d1:()=>A,fW:()=>_,w8:()=>b});var r=n(6540),a=n(6347),o=n(2831),i=n(4070),l=n(9169),s=n(1682),u=n(3886),c=n(3025),d=n(609);function f(e){const t=(0,c.r)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function p(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=p(t);if(e)return e}}(e):void 0:e.href}function m(){const{pathname:e}=(0,a.zy)(),t=(0,d.t)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=k({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}function h(){const{pathname:e}=(0,a.zy)(),t=(0,d.t)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=k({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];return n?.items??t.items}const g=(e,t)=>void 0!==e&&(0,l.ys)(e,t),y=(e,t)=>e.some((e=>b(e,t)));function b(e,t){return"link"===e.type?g(e.href,t):"category"===e.type&&(g(e.href,t)||y(e.items,t))}function v(e,t){switch(e.type){case"category":return b(e,t)||void 0!==e.href&&!e.linkUnlisted||e.items.some((e=>v(e,t)));case"link":return!e.unlisted||b(e,t);default:return!0}}function w(e,t){return(0,r.useMemo)((()=>e.filter((e=>v(e,t)))),[e,t])}function k({sidebarItems:e,pathname:t,onlyCategories:n=!1}){const r=[];return function e(a){for(const o of a)if("category"===o.type&&((0,l.ys)(o.href,t)||e(o.items))||"link"===o.type&&(0,l.ys)(o.href,t)){return n&&"category"!==o.type||r.unshift(o),!0}return!1}(e),r}function S(){const e=(0,d.t)(),{pathname:t}=(0,a.zy)(),n=(0,i.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?k({sidebarItems:e.items,pathname:t}):null}function x(e){const{activeVersion:t}=(0,i.zK)(e),{preferredVersion:n}=(0,u.g1)(e),a=(0,i.r7)(e);return(0,r.useMemo)((()=>(0,s.sb)([t,n,a].filter(Boolean))),[t,n,a])}function _(e,t){const n=x(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function E(e,t){const n=x(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,s.sb)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function C({route:e}){const t=(0,a.zy)(),n=(0,c.r)(),r=e.routes,i=r.find((e=>(0,a.B6)(t.pathname,e)));if(!i)return null;const l=i.sidebar,s=l?n.docsSidebars[l]:void 0;return{docElement:(0,o.v)(r),sidebarName:l,sidebarItems:s}}function A(e){return e.filter((e=>!("category"===e.type||"link"===e.type)||!!p(e)))}},6988:(e,t,n)=>{"use strict";n.d(t,{o:()=>d,l:()=>f});var r=n(6540),a=n(4784);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/BharatMLStack/","versions":[{"name":"current","label":"Next","isLast":true,"path":"/BharatMLStack/","mainDocId":"online-feature-store/v1.0.0/architecture","docs":[{"id":"online-feature-store/v1.0.0/architecture","path":"/BharatMLStack/online-feature-store/v1.0.0/architecture","sidebar":"tutorialSidebar"},{"id":"online-feature-store/v1.0.0/benchmarks","path":"/BharatMLStack/online-feature-store/v1.0.0/benchmarks","sidebar":"tutorialSidebar"},{"id":"online-feature-store/v1.0.0/data-formats","path":"/BharatMLStack/online-feature-store/v1.0.0/data-formats","sidebar":"tutorialSidebar"},{"id":"online-feature-store/v1.0.0/functionalities","path":"/BharatMLStack/online-feature-store/v1.0.0/functionalities","sidebar":"tutorialSidebar"},{"id":"online-feature-store/v1.0.0/release-notes","path":"/BharatMLStack/online-feature-store/v1.0.0/release-notes","sidebar":"tutorialSidebar"},{"id":"quick-start/v1.0.0/quick-start","path":"/BharatMLStack/quick-start/v1.0.0/quick-start","sidebar":"tutorialSidebar"},{"id":"sdks/go/v1.0.0/feature_client","path":"/BharatMLStack/sdks/go/v1.0.0/feature_client","sidebar":"tutorialSidebar"},{"id":"sdks/python/v1.0.0/grpc_feature_client","path":"/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client","sidebar":"tutorialSidebar"},{"id":"sdks/python/v1.0.0/spark_feature_push_client","path":"/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client","sidebar":"tutorialSidebar"},{"id":"trufflebox-ui/v1.0.0/userguide","path":"/BharatMLStack/trufflebox-ui/v1.0.0/userguide","sidebar":"tutorialSidebar"},{"id":"/category/online-feature-store","path":"/BharatMLStack/category/online-feature-store","sidebar":"tutorialSidebar"},{"id":"/online-feature-store/v1.0.0","path":"/BharatMLStack/online-feature-store/v1.0.0","sidebar":"tutorialSidebar"},{"id":"/category/quick-start","path":"/BharatMLStack/category/quick-start","sidebar":"tutorialSidebar"},{"id":"/category/trufflebox-ui","path":"/BharatMLStack/category/trufflebox-ui","sidebar":"tutorialSidebar"},{"id":"/category/sdks","path":"/BharatMLStack/category/sdks","sidebar":"tutorialSidebar"},{"id":"/category/go-sdk","path":"/BharatMLStack/category/go-sdk","sidebar":"tutorialSidebar"},{"id":"/category/python-sdk","path":"/BharatMLStack/category/python-sdk","sidebar":"tutorialSidebar"},{"id":"/category/v100","path":"/BharatMLStack/category/v100","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/BharatMLStack/category/online-feature-store","label":"Online Feature Store"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var l=n(2654);const s=JSON.parse('{"docusaurusVersion":"3.8.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-css-cascade-layers":{"type":"package","name":"@docusaurus/plugin-css-cascade-layers","version":"3.8.1"},"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.8.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.8.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.8.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.8.1"},"docusaurus-plugin-svgr":{"type":"package","name":"@docusaurus/plugin-svgr","version":"3.8.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.8.1"}}}');var u=n(4848);const c={siteConfig:a.default,siteMetadata:s,globalData:o,i18n:i,codeTranslations:l},d=r.createContext(c);function f({children:e}){return(0,u.jsx)(d.Provider,{value:c,children:e})}},7065:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});const r="default"},7489:(e,t,n)=>{"use strict";n.d(t,{A:()=>h});var r=n(6540),a=n(8193),o=n(5260),i=n(440),l=n(1656),s=n(3102),u=n(4848);function c({error:e,tryAgain:t}){return(0,u.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,u.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,u.jsx)("button",{type:"button",onClick:t,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,u.jsx)(d,{error:e})]})}function d({error:e}){const t=(0,i.rA)(e).map((e=>e.message)).join("\n\nCause:\n");return(0,u.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:t})}function f({children:e}){return(0,u.jsx)(s.W,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:e})}function p({error:e,tryAgain:t}){return(0,u.jsx)(f,{children:(0,u.jsxs)(h,{fallback:()=>(0,u.jsx)(c,{error:e,tryAgain:t}),children:[(0,u.jsx)(o.A,{children:(0,u.jsx)("title",{children:"Page Error"})}),(0,u.jsx)(l.A,{children:(0,u.jsx)(c,{error:e,tryAgain:t})})]})})}const m=e=>(0,u.jsx)(p,{...e});class h extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.A.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??m)(e)}return e??null}}},7559:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",blogAuthorsListPage:"blog-authors-list-page",blogAuthorsPostsPage:"blog-authors-posts-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",draftBanner:"theme-draft-banner",admonitionType:e=>`theme-admonition-${e}`},announcementBar:{container:"theme-announcement-bar"},layout:{navbar:{container:"theme-layout-navbar",containerLeft:"theme-layout-navbar-left",containerRight:"theme-layout-navbar-right",mobileSidebar:{container:"theme-layout-navbar-sidebar",panel:"theme-layout-navbar-sidebar-panel"}},main:{container:"theme-layout-main"},footer:{container:"theme-layout-footer",column:"theme-layout-footer-column"}},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"},pages:{pageFooterEditMetaRow:"theme-pages-footer-edit-meta-row"}}},8168:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(null,arguments)}n.d(t,{A:()=>r})},8193:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},8328:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});n(6540);var r=n(3259),a=n.n(r),o=n(4054);const i={"01a85c17":[()=>Promise.all([n.e(1869),n.e(8209)]).then(n.bind(n,9158)),"@theme/BlogTagsListPage",9158],"0413d9af":[()=>n.e(9919).then(n.bind(n,7114)),"@site/docs/sdks/python/v1.0.0/grpc_feature_client.md",7114],"09dd5be9":[()=>n.e(6273).then(n.bind(n,8831)),"@site/blog/bharatmlstack-history/post-one/index.md",8831],"0fff8dc8":[()=>n.e(9596).then(n.bind(n,5958)),"@site/docs/quick-start/v1.0.0/quick-start.md",5958],14064408:[()=>n.e(4582).then(n.t.bind(n,9416,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-quick-start-b0e.json",9416],"14eb3368":[()=>Promise.all([n.e(1869),n.e(6969)]).then(n.bind(n,477)),"@theme/DocCategoryGeneratedIndexPage",477],"176d210f":[()=>n.e(6100).then(n.bind(n,753)),"@site/docs/trufflebox-ui/v1.0.0/userguide.md",753],17896441:[()=>Promise.all([n.e(1869),n.e(6870),n.e(8401)]).then(n.bind(n,833)),"@theme/DocItem",833],"1a64de69":[()=>n.e(3645).then(n.t.bind(n,1694,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-meesho-214.json",1694],"1f391b9e":[()=>Promise.all([n.e(1869),n.e(6870),n.e(6061)]).then(n.bind(n,7973)),"@theme/MDXPage",7973],"2d865531":[()=>n.e(9197).then(n.t.bind(n,4153,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-authors-eb6.json",4153],"36994c47":[()=>n.e(9858).then(n.t.bind(n,5516,19)),"@generated/docusaurus-plugin-content-blog/default/__plugin.json",5516],"393be207":[()=>n.e(4134).then(n.bind(n,591)),"@site/src/pages/markdown-page.md",591],"3980073a":[()=>n.e(940).then(n.t.bind(n,3840,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-interaction-store-62d.json",3840],"3e1c5046":[()=>n.e(690).then(n.t.bind(n,8750,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-online-feature-store-e01.json",8750],"4137b431":[()=>n.e(6054).then(n.t.bind(n,4019,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-aad.json",4019],"44d1c015":[()=>n.e(1065).then(n.t.bind(n,6725,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-python-sdk-f96.json",6725],"479eb034":[()=>n.e(5425).then(n.t.bind(n,9341,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-mlplatform-b63.json",9341],"4af50aac":[()=>n.e(1964).then(n.bind(n,6220)),"@site/docs/sdks/go/v1.0.0/feature_client.md",6220],"4caa95bf":[()=>n.e(2344).then(n.bind(n,9584)),"@site/docs/online-feature-store/v1.0.0/data-formats.md",9584],"5e95c892":[()=>n.e(9647).then(n.bind(n,7121)),"@theme/DocsRoot",7121],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,4784)),"@generated/docusaurus.config",4784],"616111d3":[()=>n.e(9158).then(n.t.bind(n,9470,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-sdks-291.json",9470],"621db11d":[()=>Promise.all([n.e(1869),n.e(7518),n.e(4212)]).then(n.bind(n,3250)),"@theme/Blog/Pages/BlogAuthorsListPage",3250],"6479fb86":[()=>n.e(5579).then(n.t.bind(n,3751,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-archive-553.json",3751],"67d4782a":[()=>n.e(8588).then(n.bind(n,8769)),"@site/docs/online-feature-store/v1.0.0/benchmarks.md",8769],"6875c492":[()=>Promise.all([n.e(1869),n.e(6870),n.e(7518),n.e(4813)]).then(n.bind(n,3069)),"@theme/BlogTagsPostsPage",3069],"72dc5b25":[()=>n.e(8261).then(n.t.bind(n,3613,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-online-feature-store-v-1-0-0-a94.json",3613],"7fa80e1c":[()=>n.e(3322).then(n.t.bind(n,9189,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-tags-853.json",9189],"814f3328":[()=>n.e(7472).then(n.t.bind(n,5513,19)),"~blog/default/blog-post-list-prop-default.json",5513],"8ac6191a":[()=>n.e(8465).then(n.t.bind(n,4540,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-online-feature-store-8eb.json",4540],"9e4087bc":[()=>n.e(2711).then(n.bind(n,9331)),"@theme/BlogArchivePage",9331],a6aa9e1f:[()=>Promise.all([n.e(1869),n.e(6870),n.e(7518),n.e(7643)]).then(n.bind(n,5124)),"@theme/BlogListPage",5124],a7456010:[()=>n.e(1235).then(n.t.bind(n,8552,19)),"@generated/docusaurus-plugin-content-pages/default/__plugin.json",8552],a7bd4aaa:[()=>n.e(7098).then(n.bind(n,1723)),"@theme/DocVersionRoot",1723],a94703ab:[()=>Promise.all([n.e(1869),n.e(9048)]).then(n.bind(n,1377)),"@theme/DocRoot",1377],aba21aa0:[()=>n.e(5742).then(n.t.bind(n,7093,19)),"@generated/docusaurus-plugin-content-docs/default/__plugin.json",7093],ac51638e:[()=>n.e(9473).then(n.bind(n,6692)),"@site/docs/sdks/python/v1.0.0/spark_feature_push_client.md",6692],acecf23e:[()=>n.e(1903).then(n.t.bind(n,1912,19)),"~blog/default/blogMetadata-default.json",1912],c4822c4f:[()=>n.e(1915).then(n.bind(n,3649)),"@site/docs/online-feature-store/v1.0.0/functionalities.md",3649],c4f5d8e4:[()=>Promise.all([n.e(1869),n.e(2634)]).then(n.bind(n,6467)),"@site/src/pages/index.js",6467],c7b64fcc:[()=>n.e(8933).then(n.t.bind(n,9997,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-go-sdk-b5b.json",9997],ccc49370:[()=>Promise.all([n.e(1869),n.e(6870),n.e(7518),n.e(3249)]).then(n.bind(n,3858)),"@theme/BlogPostPage",3858],d152284c:[()=>n.e(1606).then(n.bind(n,5876)),"@site/docs/online-feature-store/v1.0.0/release-notes.md",5876],e66382f6:[()=>n.e(1405).then(n.bind(n,9563)),"@site/docs/online-feature-store/v1.0.0/architecture.md",9563],f2c141e4:[()=>n.e(1909).then(n.bind(n,161)),"@site/blog/bharatmlstack-history/post-one/index.md?truncated=true",161],f994c8da:[()=>n.e(1999).then(n.t.bind(n,38,19)),"@generated/docusaurus-plugin-content-blog/default/p/bharat-ml-stack-blog-7a3.json",38],fa31f022:[()=>n.e(6062).then(n.t.bind(n,6096,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-v-100-ae3.json",6096],fcf4f6ca:[()=>n.e(7720).then(n.t.bind(n,4041,19)),"@generated/docusaurus-plugin-content-docs/default/p/bharat-ml-stack-category-trufflebox-ui-b39.json",4041]};var l=n(4848);function s({error:e,retry:t,pastDelay:n}){return e?(0,l.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,l.jsx)("p",{children:String(e)}),(0,l.jsx)("div",{children:(0,l.jsx)("button",{type:"button",onClick:t,children:"Retry"})})]}):n?(0,l.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,l.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,l.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,l.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,l.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,l.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,l.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,l.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,l.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var u=n(6921),c=n(3102);function d(e,t){if("*"===e)return a()({loading:s,loader:()=>n.e(2237).then(n.bind(n,2237)),modules:["@theme/NotFound"],webpack:()=>[2237],render(e,t){const n=e.default;return(0,l.jsx)(c.W,{value:{plugin:{name:"native",id:"default"}},children:(0,l.jsx)(n,{...t})})}});const r=o[`${e}-${t}`],d={},f=[],p=[],m=(0,u.A)(r);return Object.entries(m).forEach((([e,t])=>{const n=i[t];n&&(d[e]=n[0],f.push(n[1]),p.push(n[2]))})),a().Map({loading:s,loader:d,modules:f,webpack:()=>p,render(t,n){const a=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((([t,n])=>{const r=n.default;if(!r)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof r&&"function"!=typeof r||Object.keys(n).filter((e=>"default"!==e)).forEach((e=>{r[e]=n[e]}));let o=a;const i=t.split(".");i.slice(0,-1).forEach((e=>{o=o[e]})),o[i[i.length-1]]=r}));const o=a.__comp;delete a.__comp;const i=a.__context;delete a.__context;const s=a.__props;return delete a.__props,(0,l.jsx)(c.W,{value:i,children:(0,l.jsx)(o,{...a,...s,...n})})}})}const f=[{path:"/BharatMLStack/blog",component:d("/BharatMLStack/blog","170"),exact:!0},{path:"/BharatMLStack/blog/archive",component:d("/BharatMLStack/blog/archive","dde"),exact:!0},{path:"/BharatMLStack/blog/authors",component:d("/BharatMLStack/blog/authors","f47"),exact:!0},{path:"/BharatMLStack/blog/post-one",component:d("/BharatMLStack/blog/post-one","e5f"),exact:!0},{path:"/BharatMLStack/blog/tags",component:d("/BharatMLStack/blog/tags","8af"),exact:!0},{path:"/BharatMLStack/blog/tags/interaction-store",component:d("/BharatMLStack/blog/tags/interaction-store","4b6"),exact:!0},{path:"/BharatMLStack/blog/tags/meesho",component:d("/BharatMLStack/blog/tags/meesho","316"),exact:!0},{path:"/BharatMLStack/blog/tags/mlplatform",component:d("/BharatMLStack/blog/tags/mlplatform","48f"),exact:!0},{path:"/BharatMLStack/blog/tags/online-feature-store",component:d("/BharatMLStack/blog/tags/online-feature-store","44b"),exact:!0},{path:"/BharatMLStack/markdown-page",component:d("/BharatMLStack/markdown-page","747"),exact:!0},{path:"/BharatMLStack/",component:d("/BharatMLStack/","e34"),exact:!0},{path:"/BharatMLStack/",component:d("/BharatMLStack/","fd6"),routes:[{path:"/BharatMLStack/",component:d("/BharatMLStack/","098"),routes:[{path:"/BharatMLStack/",component:d("/BharatMLStack/","925"),routes:[{path:"/BharatMLStack/category/go-sdk",component:d("/BharatMLStack/category/go-sdk","6b0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/category/online-feature-store",component:d("/BharatMLStack/category/online-feature-store","7ee"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/category/python-sdk",component:d("/BharatMLStack/category/python-sdk","1fd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/category/quick-start",component:d("/BharatMLStack/category/quick-start","dff"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/category/sdks",component:d("/BharatMLStack/category/sdks","532"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/category/trufflebox-ui",component:d("/BharatMLStack/category/trufflebox-ui","5f5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/category/v100",component:d("/BharatMLStack/category/v100","ddd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/online-feature-store/v1.0.0",component:d("/BharatMLStack/online-feature-store/v1.0.0","218"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/online-feature-store/v1.0.0/architecture",component:d("/BharatMLStack/online-feature-store/v1.0.0/architecture","0af"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/online-feature-store/v1.0.0/benchmarks",component:d("/BharatMLStack/online-feature-store/v1.0.0/benchmarks","889"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/online-feature-store/v1.0.0/data-formats",component:d("/BharatMLStack/online-feature-store/v1.0.0/data-formats","46e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/online-feature-store/v1.0.0/functionalities",component:d("/BharatMLStack/online-feature-store/v1.0.0/functionalities","415"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/online-feature-store/v1.0.0/release-notes",component:d("/BharatMLStack/online-feature-store/v1.0.0/release-notes","36c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/quick-start/v1.0.0/quick-start",component:d("/BharatMLStack/quick-start/v1.0.0/quick-start","b19"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/sdks/go/v1.0.0/feature_client",component:d("/BharatMLStack/sdks/go/v1.0.0/feature_client","1df"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client",component:d("/BharatMLStack/sdks/python/v1.0.0/grpc_feature_client","9dc"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client",component:d("/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_client","1bc"),exact:!0,sidebar:"tutorialSidebar"},{path:"/BharatMLStack/trufflebox-ui/v1.0.0/userguide",component:d("/BharatMLStack/trufflebox-ui/v1.0.0/userguide","65e"),exact:!0,sidebar:"tutorialSidebar"}]}]}]},{path:"*",component:d("*")}]},8380:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n<r;n++)t[e[n]]=!0;return t}function r(e){var n={},r=[];function a(r,o){if(!(r in n)){o.push(r);var i=o.indexOf(r);if(i<o.length-1)throw new Error("Circular dependency: "+o.slice(i).join(" -> "));var l={},s=e[r];if(s){function u(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in a(t,o),l[t]=!0,n[t])l[i]=!0}t(s.require,u),t(s.optional,u),t(s.modify,u)}n[r]=l,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),u=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a}))}return n[r]||r}}(s);i=i.map(u),l=(l||[]).map(u);var c=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(c[t]=!0,e(t))}))}));for(var f,p=r(s),m=c;a(m);){for(var h in f={},m){var g=s[h];t(g&&g.modify,(function(e){e in d&&(f[e]=!0)}))}for(var y in d)if(!(y in c))for(var b in p(y))if(b in c){f[y]=!0;break}for(var v in m=f)c[v]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,l={},s={};function u(e){if(e in l)return l[e];s[e]=!0;var a,c=[];for(var d in t(e))d in n&&c.push(d);if(0===c.length)a=r(e);else{var f=i(c.map((function(e){var t=u(e);return delete s[e],t})));o?a=o(f,(function(){return r(e)})):r(e)}return l[e]=a}for(var c in n)u(c);var d=[];for(var f in s)d.push(l[f]);return i(d)}(p,c,t,n)}};return w}}();e.exports=t},8587:(e,t,n)=>{"use strict";function r(e,t){if(null==e)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==t.indexOf(r))continue;n[r]=e[r]}return n}n.d(t,{A:()=>r})},8600:(e,t,n)=>{"use strict";var r=n(6540),a=n(5338),o=n(545),i=n(4625),l=n(4784),s=n(8193);const u=[n(3001),n(119),n(6134),n(6294),n(1043)];var c=n(8328),d=n(6347),f=n(2831),p=n(4848);function m({children:e}){return(0,p.jsx)(p.Fragment,{children:e})}var h=n(4563);const g=e=>e.defaultFormatter(e);function y({children:e}){return(0,p.jsx)(h.AL,{formatter:g,children:e})}function b({children:e}){return(0,p.jsx)(y,{children:e})}var v=n(5260),w=n(4586),k=n(6025),S=n(6342),x=n(5500),_=n(2131),E=n(4090);var C=n(440),A=n(1463);function T(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,w.A)(),r=(0,_.o)(),a=n[e].htmlLang,o=e=>e.replace("-","_");return(0,p.jsxs)(v.A,{children:[Object.entries(n).map((([e,{htmlLang:t}])=>(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:e,fullyQualified:!0}),hrefLang:t},e))),(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,p.jsx)("meta",{property:"og:locale",content:o(a)}),Object.values(n).filter((e=>a!==e.htmlLang)).map((e=>(0,p.jsx)("meta",{property:"og:locale:alternate",content:o(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function L({permalink:e}){const{siteConfig:{url:t}}=(0,w.A)(),n=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,w.A)(),{pathname:r}=(0,d.zy)();return e+(0,C.Ks)((0,k.Ay)(r),{trailingSlash:n,baseUrl:t})}(),r=e?`${t}${e}`:n;return(0,p.jsxs)(v.A,{children:[(0,p.jsx)("meta",{property:"og:url",content:r}),(0,p.jsx)("link",{rel:"canonical",href:r})]})}function j(){const{i18n:{currentLocale:e}}=(0,w.A)(),{metadata:t,image:n}=(0,S.p)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(v.A,{children:[(0,p.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,p.jsx)("body",{className:E.w})]}),n&&(0,p.jsx)(x.be,{image:n}),(0,p.jsx)(L,{}),(0,p.jsx)(T,{}),(0,p.jsx)(A.A,{tag:"default",locale:e}),(0,p.jsx)(v.A,{children:t.map(((e,t)=>(0,p.jsx)("meta",{...e},t)))})]})}const P=new Map;var N=n(6125),O=n(6988),R=n(205);function M(e,...t){const n=u.map((n=>{const r=n.default?.[e]??n[e];return r?.(...t)}));return()=>n.forEach((e=>e?.()))}const D=function({children:e,location:t,previousLocation:n}){return(0,R.A)((()=>{n!==t&&(!function({location:e,previousLocation:t}){if(!t)return;const n=e.pathname===t.pathname,r=e.hash===t.hash,a=e.search===t.search;if(n&&r&&!a)return;const{hash:o}=e;if(o){const e=decodeURIComponent(o.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:t,previousLocation:n}),M("onRouteDidUpdate",{previousLocation:n,location:t}))}),[n,t]),e};function F(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,f.u)(c.A,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class I extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.A.canUseDOM?M("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=M("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),F(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,p.jsx)(D,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(d.qh,{location:t,render:()=>e})})}}const B=I,z="__docusaurus-base-url-issue-banner-suggestion-container";function $(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '__docusaurus-base-url-issue-banner-container';\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="__docusaurus-base-url-issue-banner" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${z}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n document.body.prepend(bannerContainer);\n var suggestionContainer = document.getElementById('${z}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function U(){const{siteConfig:{baseUrl:e}}=(0,w.A)();return(0,p.jsx)(p.Fragment,{children:!s.A.canUseDOM&&(0,p.jsx)(v.A,{children:(0,p.jsx)("script",{children:$(e)})})})}function q(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,w.A)(),{pathname:n}=(0,d.zy)();return t&&n===e?(0,p.jsx)(U,{}):null}function H(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:r,localeConfigs:a}}=(0,w.A)(),o=(0,k.Ay)(e),{htmlLang:i,direction:l}=a[r];return(0,p.jsxs)(v.A,{children:[(0,p.jsx)("html",{lang:i,dir:l}),(0,p.jsx)("title",{children:t}),(0,p.jsx)("meta",{property:"og:title",content:t}),(0,p.jsx)("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&(0,p.jsx)("meta",{name:"robots",content:"noindex, nofollow"}),e&&(0,p.jsx)("link",{rel:"icon",href:o})]})}var G=n(7489),V=n(2303);function W(){const e=(0,V.A)();return(0,p.jsx)(v.A,{children:(0,p.jsx)("html",{"data-has-hydrated":e})})}const Q=(0,f.v)(c.A);function K(){const e=function(e){if(P.has(e.pathname))return{...e,pathname:P.get(e.pathname)};if((0,f.u)(c.A,e.pathname).some((({route:e})=>!0===e.exact)))return P.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return P.set(e.pathname,t),{...e,pathname:t}}((0,d.zy)());return(0,p.jsx)(B,{location:e,children:Q})}function Y(){return(0,p.jsx)(G.A,{children:(0,p.jsx)(O.l,{children:(0,p.jsxs)(N.x,{children:[(0,p.jsx)(m,{children:(0,p.jsxs)(b,{children:[(0,p.jsx)(H,{}),(0,p.jsx)(j,{}),(0,p.jsx)(q,{}),(0,p.jsx)(K,{})]})}),(0,p.jsx)(W,{})]})})})}var X=n(4054);const Z=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var J=n(6921);const ee=new Set,te=new Set,ne=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,re={prefetch:e=>{if(!(e=>!ne()&&!te.has(e)&&!ee.has(e))(e))return!1;ee.add(e);const t=(0,f.u)(c.A,e).flatMap((e=>{return t=e.route.path,Object.entries(X).filter((([e])=>e.replace(/-[^-]+$/,"")===t)).flatMap((([,e])=>Object.values((0,J.A)(e))));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Z(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!ne()&&!te.has(e))(e)&&(te.add(e),F(e))},ae=Object.freeze(re);function oe({children:e}){return"hash"===l.default.future.experimental_router?(0,p.jsx)(i.I9,{children:e}):(0,p.jsx)(i.Kd,{children:e})}const ie=Boolean(!0);if(s.A.canUseDOM){window.docusaurus=ae;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(o.vd,{children:(0,p.jsx)(oe,{children:(0,p.jsx)(Y,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},i=()=>{if(window.docusaurusRoot)window.docusaurusRoot.render(t);else if(ie)window.docusaurusRoot=a.hydrateRoot(e,t,{onRecoverableError:n});else{const r=a.createRoot(e,{onRecoverableError:n});r.render(t),window.docusaurusRoot=r}};F(window.location.pathname).then((()=>{(0,r.startTransition)(i)}))}},8692:(e,t,n)=>{var r={"./":8722};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=8692},8722:(e,t,n)=>{const r=n(6969),a=n(8380),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(3157).resolve(t)],delete Prism.languages[e],n(3157)(t),o.add(e)}))}i.silent=!1,e.exports=i},8774:(e,t,n)=>{"use strict";n.d(t,{A:()=>p});var r=n(6540),a=n(4625),o=n(440),i=n(4586),l=n(6654),s=n(8193),u=n(3427),c=n(6025),d=n(4848);function f({isNavLink:e,to:t,href:n,activeClassName:f,isActive:p,"data-noBrokenLinkCheck":m,autoAddBaseUrl:h=!0,...g},y){const{siteConfig:b}=(0,i.A)(),{trailingSlash:v,baseUrl:w}=b,k=b.future.experimental_router,{withBaseUrl:S}=(0,c.hH)(),x=(0,u.A)(),_=(0,r.useRef)(null);(0,r.useImperativeHandle)(y,(()=>_.current));const E=t||n;const C=(0,l.A)(E),A=E?.replace("pathname://","");let T=void 0!==A?(L=A,h&&(e=>e.startsWith("/"))(L)?S(L):L):void 0;var L;"hash"===k&&T?.startsWith("./")&&(T=T?.slice(1)),T&&C&&(T=(0,o.Ks)(T,{trailingSlash:v,baseUrl:w}));const j=(0,r.useRef)(!1),P=e?a.k2:a.N_,N=s.A.canUseIntersectionObserver,O=(0,r.useRef)(),R=()=>{j.current||null==T||(window.docusaurus.preload(T),j.current=!0)};(0,r.useEffect)((()=>(!N&&C&&s.A.canUseDOM&&null!=T&&window.docusaurus.prefetch(T),()=>{N&&O.current&&O.current.disconnect()})),[O,T,N,C]);const M=T?.startsWith("#")??!1,D=!g.target||"_self"===g.target,F=!T||!C||!D||M&&"hash"!==k;m||!M&&F||x.collectLink(T),g.id&&x.collectAnchor(g.id);const I={};return F?(0,d.jsx)("a",{ref:_,href:T,...E&&!C&&{target:"_blank",rel:"noopener noreferrer"},...g,...I}):(0,d.jsx)(P,{...g,onMouseEnter:R,onTouchStart:R,innerRef:e=>{_.current=e,N&&e&&C&&(O.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(O.current.unobserve(e),O.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),O.current.observe(e))},to:T,...e&&{isActive:p,activeClassName:f},...I})}const p=r.forwardRef(f)},9169:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>l,ys:()=>i});var r=n(6540),a=n(8328),o=n(4586);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function l(){const{baseUrl:e}=(0,o.A)().siteConfig;return(0,r.useMemo)((()=>function({baseUrl:e,routes:t}){function n(t){return t.path===e&&!0===t.exact}function r(t){return t.path===e&&!t.exact}return function e(t){if(0===t.length)return;return t.find(n)||e(t.filter(r).flatMap((e=>e.routes??[])))}(t)}({routes:a.A,baseUrl:e})),[e])}},9532:(e,t,n)=>{"use strict";n.d(t,{Be:()=>u,ZC:()=>l,_q:()=>i,dV:()=>s,fM:()=>c});var r=n(6540),a=n(205),o=n(4848);function i(e){const t=(0,r.useRef)(e);return(0,a.A)((()=>{t.current=e}),[e]),(0,r.useCallback)(((...e)=>t.current(...e)),[])}function l(e){const t=(0,r.useRef)();return(0,a.A)((()=>{t.current=e})),t.current}class s extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function u(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function c(e){return({children:t})=>(0,o.jsx)(o.Fragment,{children:e.reduceRight(((e,t)=>(0,o.jsx)(t,{children:e})),t)})}},9698:(e,t)=>{"use strict";var n=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function a(e,t,r){var a=null;if(void 0!==r&&(a=""+r),void 0!==t.key&&(a=""+t.key),"key"in t)for(var o in r={},t)"key"!==o&&(r[o]=t[o]);else r=t;return t=r.ref,{$$typeof:n,type:e,key:a,ref:void 0!==t?t:null,props:r}}t.Fragment=r,t.jsx=a,t.jsxs=a},9700:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,l=i.length;-1!==n.code.indexOf(a=t(r,l));)++l;return i[l]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(l){for(var s=0;s<l.length&&!(a>=o.length);s++){var u=l[s];if("string"==typeof u||u.content&&"string"==typeof u.content){var c=o[a],d=n.tokenStack[c],f="string"==typeof u?u:u.content,p=t(r,c),m=f.indexOf(p);if(m>-1){++a;var h=f.substring(0,m),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),y=f.substring(m+p.length),b=[];h&&b.push.apply(b,i([h])),b.push(g),y&&b.push.apply(b,i([y])),"string"==typeof u?l.splice.apply(l,[s,1].concat(b)):u.content=b}}else u.content&&i(u.content)}return l}(n.tokens)}}}})}(Prism)},9869:(e,t)=>{"use strict";var n=Symbol.for("react.transitional.element"),r=Symbol.for("react.portal"),a=Symbol.for("react.fragment"),o=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),l=Symbol.for("react.consumer"),s=Symbol.for("react.context"),u=Symbol.for("react.forward_ref"),c=Symbol.for("react.suspense"),d=Symbol.for("react.memo"),f=Symbol.for("react.lazy"),p=Symbol.iterator;var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},h=Object.assign,g={};function y(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}function b(){}function v(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}y.prototype.isReactComponent={},y.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},y.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},b.prototype=y.prototype;var w=v.prototype=new b;w.constructor=v,h(w,y.prototype),w.isPureReactComponent=!0;var k=Array.isArray,S={H:null,A:null,T:null,S:null,V:null},x=Object.prototype.hasOwnProperty;function _(e,t,r,a,o,i){return r=i.ref,{$$typeof:n,type:e,key:t,ref:void 0!==r?r:null,props:i}}function E(e){return"object"==typeof e&&null!==e&&e.$$typeof===n}var C=/\/+/g;function A(e,t){return"object"==typeof e&&null!==e&&null!=e.key?(n=""+e.key,r={"=":"=0",":":"=2"},"$"+n.replace(/[=:]/g,(function(e){return r[e]}))):t.toString(36);var n,r}function T(){}function L(e,t,a,o,i){var l=typeof e;"undefined"!==l&&"boolean"!==l||(e=null);var s,u,c=!1;if(null===e)c=!0;else switch(l){case"bigint":case"string":case"number":c=!0;break;case"object":switch(e.$$typeof){case n:case r:c=!0;break;case f:return L((c=e._init)(e._payload),t,a,o,i)}}if(c)return i=i(e),c=""===o?"."+A(e,0):o,k(i)?(a="",null!=c&&(a=c.replace(C,"$&/")+"/"),L(i,t,a,"",(function(e){return e}))):null!=i&&(E(i)&&(s=i,u=a+(null==i.key||e&&e.key===i.key?"":(""+i.key).replace(C,"$&/")+"/")+c,i=_(s.type,u,void 0,0,0,s.props)),t.push(i)),1;c=0;var d,m=""===o?".":o+":";if(k(e))for(var h=0;h<e.length;h++)c+=L(o=e[h],t,a,l=m+A(o,h),i);else if("function"==typeof(h=null===(d=e)||"object"!=typeof d?null:"function"==typeof(d=p&&d[p]||d["@@iterator"])?d:null))for(e=h.call(e),h=0;!(o=e.next()).done;)c+=L(o=o.value,t,a,l=m+A(o,h++),i);else if("object"===l){if("function"==typeof e.then)return L(function(e){switch(e.status){case"fulfilled":return e.value;case"rejected":throw e.reason;default:switch("string"==typeof e.status?e.then(T,T):(e.status="pending",e.then((function(t){"pending"===e.status&&(e.status="fulfilled",e.value=t)}),(function(t){"pending"===e.status&&(e.status="rejected",e.reason=t)}))),e.status){case"fulfilled":return e.value;case"rejected":throw e.reason}}throw e}(e),t,a,o,i);throw t=String(e),Error("Objects are not valid as a React child (found: "+("[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.")}return c}function j(e,t,n){if(null==e)return e;var r=[],a=0;return L(e,r,"","",(function(e){return t.call(n,e,a++)})),r}function P(e){if(-1===e._status){var t=e._result;(t=t()).then((function(t){0!==e._status&&-1!==e._status||(e._status=1,e._result=t)}),(function(t){0!==e._status&&-1!==e._status||(e._status=2,e._result=t)})),-1===e._status&&(e._status=0,e._result=t)}if(1===e._status)return e._result.default;throw e._result}var N="function"==typeof reportError?reportError:function(e){if("object"==typeof window&&"function"==typeof window.ErrorEvent){var t=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:"object"==typeof e&&null!==e&&"string"==typeof e.message?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if("object"==typeof process&&"function"==typeof process.emit)return void process.emit("uncaughtException",e);console.error(e)};function O(){}t.Children={map:j,forEach:function(e,t,n){j(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return j(e,(function(){t++})),t},toArray:function(e){return j(e,(function(e){return e}))||[]},only:function(e){if(!E(e))throw Error("React.Children.only expected to receive a single React element child.");return e}},t.Component=y,t.Fragment=a,t.Profiler=i,t.PureComponent=v,t.StrictMode=o,t.Suspense=c,t.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=S,t.__COMPILER_RUNTIME={__proto__:null,c:function(e){return S.H.useMemoCache(e)}},t.cache=function(e){return function(){return e.apply(null,arguments)}},t.cloneElement=function(e,t,n){if(null==e)throw Error("The argument must be a React element, but you passed "+e+".");var r=h({},e.props),a=e.key;if(null!=t)for(o in void 0!==t.ref&&void 0,void 0!==t.key&&(a=""+t.key),t)!x.call(t,o)||"key"===o||"__self"===o||"__source"===o||"ref"===o&&void 0===t.ref||(r[o]=t[o]);var o=arguments.length-2;if(1===o)r.children=n;else if(1<o){for(var i=Array(o),l=0;l<o;l++)i[l]=arguments[l+2];r.children=i}return _(e.type,a,void 0,0,0,r)},t.createContext=function(e){return(e={$$typeof:s,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider=e,e.Consumer={$$typeof:l,_context:e},e},t.createElement=function(e,t,n){var r,a={},o=null;if(null!=t)for(r in void 0!==t.key&&(o=""+t.key),t)x.call(t,r)&&"key"!==r&&"__self"!==r&&"__source"!==r&&(a[r]=t[r]);var i=arguments.length-2;if(1===i)a.children=n;else if(1<i){for(var l=Array(i),s=0;s<i;s++)l[s]=arguments[s+2];a.children=l}if(e&&e.defaultProps)for(r in i=e.defaultProps)void 0===a[r]&&(a[r]=i[r]);return _(e,o,void 0,0,0,a)},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:u,render:e}},t.isValidElement=E,t.lazy=function(e){return{$$typeof:f,_payload:{_status:-1,_result:e},_init:P}},t.memo=function(e,t){return{$$typeof:d,type:e,compare:void 0===t?null:t}},t.startTransition=function(e){var t=S.T,n={};S.T=n;try{var r=e(),a=S.S;null!==a&&a(n,r),"object"==typeof r&&null!==r&&"function"==typeof r.then&&r.then(O,N)}catch(o){N(o)}finally{S.T=t}},t.unstable_useCacheRefresh=function(){return S.H.useCacheRefresh()},t.use=function(e){return S.H.use(e)},t.useActionState=function(e,t,n){return S.H.useActionState(e,t,n)},t.useCallback=function(e,t){return S.H.useCallback(e,t)},t.useContext=function(e){return S.H.useContext(e)},t.useDebugValue=function(){},t.useDeferredValue=function(e,t){return S.H.useDeferredValue(e,t)},t.useEffect=function(e,t,n){var r=S.H;if("function"==typeof n)throw Error("useEffect CRUD overload is not enabled in this build of React.");return r.useEffect(e,t)},t.useId=function(){return S.H.useId()},t.useImperativeHandle=function(e,t,n){return S.H.useImperativeHandle(e,t,n)},t.useInsertionEffect=function(e,t){return S.H.useInsertionEffect(e,t)},t.useLayoutEffect=function(e,t){return S.H.useLayoutEffect(e,t)},t.useMemo=function(e,t){return S.H.useMemo(e,t)},t.useOptimistic=function(e,t){return S.H.useOptimistic(e,t)},t.useReducer=function(e,t,n){return S.H.useReducer(e,t,n)},t.useRef=function(e){return S.H.useRef(e)},t.useState=function(e){return S.H.useState(e)},t.useSyncExternalStore=function(e,t,n){return S.H.useSyncExternalStore(e,t,n)},t.useTransition=function(){return S.H.useTransition()},t.version="19.1.0"},9876:(e,t,n)=>{"use strict";n.d(t,{e:()=>m,M:()=>h});var r=n(6540),a=n(5600),o=n(4581),i=n(6347),l=n(9532);function s(e){!function(e){const t=(0,i.W6)(),n=(0,l._q)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var u=n(6342),c=n(4848);const d=r.createContext(void 0);function f(){const e=function(){const e=(0,a.YL)(),{items:t}=(0,u.p)().navbar;return 0===t.length&&!e.component}(),t=(0,o.l)(),n=!e&&"mobile"===t,[i,l]=(0,r.useState)(!1),s=(0,r.useCallback)((()=>{l((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&l(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:s,shown:i})),[e,n,s,i])}function p({handler:e}){return s(e),null}function m({children:e}){const t=f();return(0,c.jsxs)(c.Fragment,{children:[t.shown&&(0,c.jsx)(p,{handler:()=>(t.toggle(),!1)}),(0,c.jsx)(d.Provider,{value:t,children:e})]})}function h(){const e=r.useContext(d);if(void 0===e)throw new l.dV("NavbarMobileSidebarProvider");return e}},9982:(e,t,n)=>{"use strict";e.exports=n(4477)}},e=>{e.O(0,[1869],(()=>{return t=8600,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/docs/assets/js/runtime~main.ac134f18.js b/docs/assets/js/runtime~main.ac134f18.js deleted file mode 100644 index 941cca7e..00000000 --- a/docs/assets/js/runtime~main.ac134f18.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{"use strict";var e,a,c,t,r,f={},d={};function o(e){var a=d[e];if(void 0!==a)return a.exports;var c=d[e]={id:e,loaded:!1,exports:{}};return f[e].call(c.exports,c,c.exports,o),c.loaded=!0,c.exports}o.m=f,o.c=d,e=[],o.O=(a,c,t,r)=>{if(!c){var f=1/0;for(i=0;i<e.length;i++){c=e[i][0],t=e[i][1],r=e[i][2];for(var d=!0,n=0;n<c.length;n++)(!1&r||f>=r)&&Object.keys(o.O).every((e=>o.O[e](c[n])))?c.splice(n--,1):(d=!1,r<f&&(f=r));if(d){e.splice(i--,1);var b=t();void 0!==b&&(a=b)}}return a}r=r||0;for(var i=e.length;i>0&&e[i-1][2]>r;i--)e[i]=e[i-1];e[i]=[c,t,r]},o.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return o.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,o.t=function(e,t){if(1&t&&(e=this(e)),8&t)return e;if("object"==typeof e&&e){if(4&t&&e.__esModule)return e;if(16&t&&"function"==typeof e.then)return e}var r=Object.create(null);o.r(r);var f={};a=a||[null,c({}),c([]),c(c)];for(var d=2&t&&e;"object"==typeof d&&!~a.indexOf(d);d=c(d))Object.getOwnPropertyNames(d).forEach((a=>f[a]=()=>e[a]));return f.default=()=>e,o.d(r,f),r},o.d=(e,a)=>{for(var c in a)o.o(a,c)&&!o.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce(((a,c)=>(o.f[c](e,a),a)),[])),o.u=e=>"assets/js/"+({690:"3e1c5046",940:"3980073a",1065:"44d1c015",1235:"a7456010",1405:"e66382f6",1606:"d152284c",1903:"acecf23e",1909:"f2c141e4",1915:"c4822c4f",1964:"4af50aac",1999:"f994c8da",2344:"4caa95bf",2634:"c4f5d8e4",2711:"9e4087bc",3249:"ccc49370",3322:"7fa80e1c",3645:"1a64de69",4134:"393be207",4212:"621db11d",4582:"14064408",4813:"6875c492",5425:"479eb034",5579:"6479fb86",5742:"aba21aa0",6054:"4137b431",6061:"1f391b9e",6062:"fa31f022",6100:"176d210f",6273:"09dd5be9",6969:"14eb3368",7098:"a7bd4aaa",7472:"814f3328",7643:"a6aa9e1f",7720:"fcf4f6ca",8209:"01a85c17",8261:"72dc5b25",8401:"17896441",8465:"8ac6191a",8588:"67d4782a",8933:"c7b64fcc",9048:"a94703ab",9158:"616111d3",9197:"2d865531",9473:"ac51638e",9596:"0fff8dc8",9647:"5e95c892",9858:"36994c47",9919:"0413d9af"}[e]||e)+"."+{690:"22a78085",940:"4ab85476",1065:"4db6c425",1235:"5f9bbb01",1405:"aaa6c9c6",1606:"8adb699d",1903:"4b2b5a9c",1909:"e3b70339",1915:"9fe3ec4e",1964:"a113ce2d",1999:"90063f83",2237:"bfceba09",2344:"2e5bda05",2634:"f5d4db47",2711:"b154716b",3249:"8f9e0351",3322:"b5f726bf",3645:"22893b6e",4134:"81b456e5",4212:"515621df",4582:"be0f96be",4813:"72d20027",5425:"0c88dc68",5579:"d4723af3",5742:"ed09cce9",6054:"2e5cd4ca",6061:"8e4379a0",6062:"c62034f4",6100:"47d21595",6273:"9cd209bb",6870:"6d10e1d8",6969:"e9006523",7098:"8da7b7a1",7472:"b45803b6",7518:"6ac3b679",7643:"a34fe105",7720:"d9bac5e5",8209:"5487421a",8261:"e57720a7",8401:"e023d99a",8465:"6f3973a2",8588:"09ac845b",8933:"9ff95135",9048:"50a268a2",9158:"9f2925b1",9197:"a5005531",9473:"cd23cca0",9596:"7a470540",9647:"a6c239e7",9858:"337a7516",9919:"cb9ba41f"}[e]+".js",o.miniCssF=e=>{},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),t={},r="docs:",o.l=(e,a,c,f)=>{if(t[e])t[e].push(a);else{var d,n;if(void 0!==c)for(var b=document.getElementsByTagName("script"),i=0;i<b.length;i++){var u=b[i];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==r+c){d=u;break}}d||(n=!0,(d=document.createElement("script")).charset="utf-8",d.timeout=120,o.nc&&d.setAttribute("nonce",o.nc),d.setAttribute("data-webpack",r+c),d.src=e),t[e]=[a];var l=(a,c)=>{d.onerror=d.onload=null,clearTimeout(s);var r=t[e];if(delete t[e],d.parentNode&&d.parentNode.removeChild(d),r&&r.forEach((e=>e(c))),a)return a(c)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:d}),12e4);d.onerror=l.bind(null,d.onerror),d.onload=l.bind(null,d.onload),n&&document.head.appendChild(d)}},o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.p="/BharatMLStack/",o.gca=function(e){return e={14064408:"4582",17896441:"8401","3e1c5046":"690","3980073a":"940","44d1c015":"1065",a7456010:"1235",e66382f6:"1405",d152284c:"1606",acecf23e:"1903",f2c141e4:"1909",c4822c4f:"1915","4af50aac":"1964",f994c8da:"1999","4caa95bf":"2344",c4f5d8e4:"2634","9e4087bc":"2711",ccc49370:"3249","7fa80e1c":"3322","1a64de69":"3645","393be207":"4134","621db11d":"4212","6875c492":"4813","479eb034":"5425","6479fb86":"5579",aba21aa0:"5742","4137b431":"6054","1f391b9e":"6061",fa31f022:"6062","176d210f":"6100","09dd5be9":"6273","14eb3368":"6969",a7bd4aaa:"7098","814f3328":"7472",a6aa9e1f:"7643",fcf4f6ca:"7720","01a85c17":"8209","72dc5b25":"8261","8ac6191a":"8465","67d4782a":"8588",c7b64fcc:"8933",a94703ab:"9048","616111d3":"9158","2d865531":"9197",ac51638e:"9473","0fff8dc8":"9596","5e95c892":"9647","36994c47":"9858","0413d9af":"9919"}[e]||e,o.p+o.u(e)},(()=>{var e={5354:0,1869:0};o.f.j=(a,c)=>{var t=o.o(e,a)?e[a]:void 0;if(0!==t)if(t)c.push(t[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var r=new Promise(((c,r)=>t=e[a]=[c,r]));c.push(t[2]=r);var f=o.p+o.u(a),d=new Error;o.l(f,(c=>{if(o.o(e,a)&&(0!==(t=e[a])&&(e[a]=void 0),t)){var r=c&&("load"===c.type?"missing":c.type),f=c&&c.target&&c.target.src;d.message="Loading chunk "+a+" failed.\n("+r+": "+f+")",d.name="ChunkLoadError",d.type=r,d.request=f,t[1](d)}}),"chunk-"+a,a)}},o.O.j=a=>0===e[a];var a=(a,c)=>{var t,r,f=c[0],d=c[1],n=c[2],b=0;if(f.some((a=>0!==e[a]))){for(t in d)o.o(d,t)&&(o.m[t]=d[t]);if(n)var i=n(o)}for(a&&a(c);b<f.length;b++)r=f[b],o.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return o.O(i)},c=self.webpackChunkdocs=self.webpackChunkdocs||[];c.forEach(a.bind(null,0)),c.push=a.bind(null,c.push.bind(c))})()})(); \ No newline at end of file diff --git a/docs/assets/js/runtime~main.d5e46064.js b/docs/assets/js/runtime~main.d5e46064.js new file mode 100644 index 00000000..6ac5687e --- /dev/null +++ b/docs/assets/js/runtime~main.d5e46064.js @@ -0,0 +1 @@ +(()=>{"use strict";var e,a,c,f,d,t={},r={};function b(e){var a=r[e];if(void 0!==a)return a.exports;var c=r[e]={id:e,loaded:!1,exports:{}};return t[e].call(c.exports,c,c.exports,b),c.loaded=!0,c.exports}b.m=t,b.c=r,e=[],b.O=(a,c,f,d)=>{if(!c){var t=1/0;for(i=0;i<e.length;i++){c=e[i][0],f=e[i][1],d=e[i][2];for(var r=!0,o=0;o<c.length;o++)(!1&d||t>=d)&&Object.keys(b.O).every(e=>b.O[e](c[o]))?c.splice(o--,1):(r=!1,d<t&&(t=d));if(r){e.splice(i--,1);var n=f();void 0!==n&&(a=n)}}return a}d=d||0;for(var i=e.length;i>0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[c,f,d]},b.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return b.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,b.t=function(e,f){if(1&f&&(e=this(e)),8&f)return e;if("object"==typeof e&&e){if(4&f&&e.__esModule)return e;if(16&f&&"function"==typeof e.then)return e}var d=Object.create(null);b.r(d);var t={};a=a||[null,c({}),c([]),c(c)];for(var r=2&f&&e;("object"==typeof r||"function"==typeof r)&&!~a.indexOf(r);r=c(r))Object.getOwnPropertyNames(r).forEach(a=>t[a]=()=>e[a]);return t.default=()=>e,b.d(d,t),d},b.d=(e,a)=>{for(var c in a)b.o(a,c)&&!b.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},b.f={},b.e=e=>Promise.all(Object.keys(b.f).reduce((a,c)=>(b.f[c](e,a),a),[])),b.u=e=>"assets/js/"+({690:"3e1c5046",770:"aaabe254",940:"3980073a",974:"3aeb33c7",1009:"50899a24",1065:"44d1c015",1235:"a7456010",1405:"e66382f6",1537:"8dd2df60",1606:"d152284c",1686:"08daf6b6",1903:"acecf23e",1909:"f2c141e4",1915:"c4822c4f",1964:"4af50aac",1999:"f994c8da",2117:"fccc4c42",2344:"4caa95bf",2379:"4df0e30b",2634:"c4f5d8e4",2711:"9e4087bc",2771:"e8202a51",2951:"9aed321e",3249:"ccc49370",3322:"7fa80e1c",3645:"1a64de69",4064:"99009a21",4134:"393be207",4212:"621db11d",4340:"79ae4ea7",4416:"93f344c7",4424:"252a9097",4582:"14064408",4771:"3216e812",4813:"6875c492",5425:"479eb034",5503:"428aafcc",5579:"6479fb86",5742:"aba21aa0",5801:"2c62ead1",6054:"4137b431",6061:"1f391b9e",6062:"fa31f022",6100:"176d210f",6273:"09dd5be9",6724:"a97f18d9",6969:"14eb3368",7048:"00b12b9c",7098:"a7bd4aaa",7472:"814f3328",7508:"0a89f5c9",7609:"adb039a4",7643:"a6aa9e1f",7720:"fcf4f6ca",7871:"be9e6e2d",8014:"9d13045e",8209:"01a85c17",8261:"72dc5b25",8315:"f9755c6e",8401:"17896441",8465:"8ac6191a",8588:"67d4782a",8933:"c7b64fcc",9048:"a94703ab",9158:"616111d3",9197:"2d865531",9226:"6bb91276",9473:"ac51638e",9596:"0fff8dc8",9647:"5e95c892",9824:"8ea48c46",9858:"36994c47",9919:"0413d9af",9955:"45a03d07"}[e]||e)+"."+{690:"22a78085",770:"ba3e9f5f",940:"43116f8b",974:"b4a8c40f",1009:"c0cfae29",1065:"4db6c425",1235:"5f9bbb01",1405:"ad26fd04",1537:"f10b075c",1606:"0800e671",1686:"852abb6b",1903:"4b2b5a9c",1909:"7dc49a6b",1915:"c80625fe",1964:"f9b29cbf",1999:"256af20d",2117:"4690f84a",2237:"bfceba09",2344:"ca3bb1d0",2379:"00b3a0ff",2634:"41d5b3c8",2711:"342bf9bc",2771:"49541ad2",2951:"0ede45c0",3249:"1c88001f",3322:"78f6a21e",3645:"844e372c",4064:"1a57fa22",4134:"6e979fd2",4212:"1a835b77",4340:"1416ba4f",4416:"7cebeb9e",4424:"3acfe41e",4582:"74c23df4",4771:"877aa30c",4813:"7e263e94",5425:"fc01692f",5503:"2c1db158",5579:"96631f8d",5742:"ed09cce9",5801:"fc5c1b17",6054:"c6fedbd3",6061:"4acd5995",6062:"968b3373",6100:"21c450d1",6273:"be7fd2aa",6724:"ce4ddba2",6870:"25f53758",6969:"398ac934",7048:"ea8fba0b",7098:"8da7b7a1",7472:"bfb123e8",7508:"190be82b",7518:"9525ffbe",7609:"c0c263a3",7643:"e531d6c8",7720:"d9bac5e5",7871:"944ea2f0",8014:"3f255bd8",8209:"9618aedf",8261:"20421ae4",8315:"8811662b",8401:"4ff7d852",8465:"6f3973a2",8588:"96733ef0",8933:"9ff95135",9048:"3a38a667",9158:"9f2925b1",9197:"3ec70534",9226:"d5be09e8",9473:"ef64a004",9596:"fcba975a",9647:"7a2663a1",9824:"e52cd527",9858:"337a7516",9919:"aecac3d5",9955:"6212d749"}[e]+".js",b.miniCssF=e=>{},b.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),b.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),f={},d="docs:",b.l=(e,a,c,t)=>{if(f[e])f[e].push(a);else{var r,o;if(void 0!==c)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var u=n[i];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==d+c){r=u;break}}r||(o=!0,(r=document.createElement("script")).charset="utf-8",r.timeout=120,b.nc&&r.setAttribute("nonce",b.nc),r.setAttribute("data-webpack",d+c),r.src=e),f[e]=[a];var l=(a,c)=>{r.onerror=r.onload=null,clearTimeout(s);var d=f[e];if(delete f[e],r.parentNode&&r.parentNode.removeChild(r),d&&d.forEach(e=>e(c)),a)return a(c)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:r}),12e4);r.onerror=l.bind(null,r.onerror),r.onload=l.bind(null,r.onload),o&&document.head.appendChild(r)}},b.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},b.p="/BharatMLStack/",b.gca=function(e){return e={14064408:"4582",17896441:"8401","3e1c5046":"690",aaabe254:"770","3980073a":"940","3aeb33c7":"974","50899a24":"1009","44d1c015":"1065",a7456010:"1235",e66382f6:"1405","8dd2df60":"1537",d152284c:"1606","08daf6b6":"1686",acecf23e:"1903",f2c141e4:"1909",c4822c4f:"1915","4af50aac":"1964",f994c8da:"1999",fccc4c42:"2117","4caa95bf":"2344","4df0e30b":"2379",c4f5d8e4:"2634","9e4087bc":"2711",e8202a51:"2771","9aed321e":"2951",ccc49370:"3249","7fa80e1c":"3322","1a64de69":"3645","99009a21":"4064","393be207":"4134","621db11d":"4212","79ae4ea7":"4340","93f344c7":"4416","252a9097":"4424","3216e812":"4771","6875c492":"4813","479eb034":"5425","428aafcc":"5503","6479fb86":"5579",aba21aa0:"5742","2c62ead1":"5801","4137b431":"6054","1f391b9e":"6061",fa31f022:"6062","176d210f":"6100","09dd5be9":"6273",a97f18d9:"6724","14eb3368":"6969","00b12b9c":"7048",a7bd4aaa:"7098","814f3328":"7472","0a89f5c9":"7508",adb039a4:"7609",a6aa9e1f:"7643",fcf4f6ca:"7720",be9e6e2d:"7871","9d13045e":"8014","01a85c17":"8209","72dc5b25":"8261",f9755c6e:"8315","8ac6191a":"8465","67d4782a":"8588",c7b64fcc:"8933",a94703ab:"9048","616111d3":"9158","2d865531":"9197","6bb91276":"9226",ac51638e:"9473","0fff8dc8":"9596","5e95c892":"9647","8ea48c46":"9824","36994c47":"9858","0413d9af":"9919","45a03d07":"9955"}[e]||e,b.p+b.u(e)},(()=>{var e={5354:0,1869:0};b.f.j=(a,c)=>{var f=b.o(e,a)?e[a]:void 0;if(0!==f)if(f)c.push(f[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var d=new Promise((c,d)=>f=e[a]=[c,d]);c.push(f[2]=d);var t=b.p+b.u(a),r=new Error;b.l(t,c=>{if(b.o(e,a)&&(0!==(f=e[a])&&(e[a]=void 0),f)){var d=c&&("load"===c.type?"missing":c.type),t=c&&c.target&&c.target.src;r.message="Loading chunk "+a+" failed.\n("+d+": "+t+")",r.name="ChunkLoadError",r.type=d,r.request=t,f[1](r)}},"chunk-"+a,a)}},b.O.j=a=>0===e[a];var a=(a,c)=>{var f,d,t=c[0],r=c[1],o=c[2],n=0;if(t.some(a=>0!==e[a])){for(f in r)b.o(r,f)&&(b.m[f]=r[f]);if(o)var i=o(b)}for(a&&a(c);n<t.length;n++)d=t[n],b.o(e,d)&&e[d]&&e[d][0](),e[d]=0;return b.O(i)},c=self.webpackChunkdocs=self.webpackChunkdocs||[];c.forEach(a.bind(null,0)),c.push=a.bind(null,c.push.bind(c))})()})(); \ No newline at end of file diff --git a/docs/blog/archive/index.html b/docs/blog/archive/index.html index a0076431..614e27f6 100644 --- a/docs/blog/archive/index.html +++ b/docs/blog/archive/index.html @@ -4,14 +4,14 @@ <meta charset="UTF-8"> <meta name="generator" content="Docusaurus v3.8.1"> <title data-rh="true">Archive | BharatMLStack - - - + + + - + \ No newline at end of file diff --git a/docs/blog/atom.xml b/docs/blog/atom.xml index 84514334..321c11b1 100644 --- a/docs/blog/atom.xml +++ b/docs/blog/atom.xml @@ -2,18 +2,673 @@ https://meesho.github.io/BharatMLStack/blog BharatMLStack Blog - 2022-11-15T00:00:00.000Z + 2025-06-02T00:00:00.000Z https://github.com/jpmonette/feed BharatMLStack Blog https://meesho.github.io/BharatMLStack/img/favicon.ico + + <![CDATA[LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale]]> + https://meesho.github.io/BharatMLStack/blog/post-five + + 2025-06-02T00:00:00.000Z + + BharatMLStack

+

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

+

Raw execution of Large Language Models is inherently expensive and memory-intensive. To achieve sub-second latency and high throughput, we implement a multi-layered optimization strategy that targets the entire inference stack—from memory management to kernel execution.

+

1. Advanced Memory Management: Paged & Prefix KV Caching

+

The most significant bottleneck in LLM inference is not always compute, but memory bandwidth—specifically managing the Key-Value (KV) cache.

+

Paged KV caching

+

Standard caching suffers from fragmentation. We use Paged KV caching, which operates similarly to an operating system's virtual memory: the KV cache is divided into non-contiguous blocks. This lets us serve larger batch sizes without running out of memory.

+

KV cache quantization

+

To further maximize available memory, we implement KV cache quantization (e.g., FP8). By compressing stored attention keys and values from 16-bit to 8-bit, we nearly double the effective context window capacity of the GPU, allowing longer conversations or larger batches without materially degrading quality.

+

Prefix caching (the "voice bot" optimizer)

+

For use cases like GenAI voice bots where the system prompt (e.g., "You are a helpful assistant...") is static across thousands of requests, we enable prefix caching.

+
    +
  • Impact: By reusing pre-computed KV states for common prefixes, we achieve a cache hit rate of ~90%. This reduces Time To First Token (TTFT) by skipping redundant computation of the system prompt.
  • +
+

2. Aggressive Quantization (INT4 AWQ & FP8)

+

Running models in their native 16-bit precision (BF16) restricts maximum batch size and throughput. We use quantization to shrink model weights without sacrificing accuracy.

+

INT4 AWQ (Activation-aware Weight Quantization)

+

For the Llama 3 family, we use AWQ to compress weights to 4 bits. This reduces model size by ~75%, allowing larger models to fit into L4 GPU memory and significantly improving token generation speed.

+

FP8 precision

+

For NVIDIA Hopper (H100) architectures, we are exploring FP8 quantization, leveraging native FP8 tensor cores to accelerate matrix multiplications while maintaining a higher dynamic range than integer quantization.

+
    +
  • Verification: We validate quantized models by comparing dot-product similarity of embeddings against the FP16 baseline, consistently achieving >99% similarity.
  • +
+

3. Kernel Fusion & Custom Plugins

+

To minimize overhead from launching thousands of small GPU operations, we fuse them into monolithic kernels using NVIDIA TensorRT plugins.

+
    +
  • Flash attention & FMHA: We enable Fused Multi-Head Attention (FMHA) combined with flash attention to reduce memory reads/writes.
  • +
  • GEMM plugins: We use specialized GEMM plugins to accelerate transformer linear layers.
  • +
  • Removing input padding: Instead of padding short sequences to match the longest, we remove input padding so the GPU processes only valid tokens.
  • +
+

4. Inflight (Continuous) Batching

+

Traditional static batching waits for all requests in a batch to finish before returning results—so one long response delays everyone else.

+

We implement inflight batching: as soon as one request completes, its slot is freed and filled by a new request from the queue. This keeps GPUs saturated and decouples latency of short queries from long ones.

+

5. Parallelism Strategies: Scaling Beyond One GPU

+

For large models (e.g., 70B+ parameters) that cannot fit into the VRAM of a single GPU, we use parallelism strategies.

+
    +
  • Tensor parallelism (TP): Split weight matrices across multiple GPUs (e.g., 4× L4 or 8× A100). Each GPU computes a shard and outputs are reduced at every layer.
  • +
  • Pipeline parallelism (PP): Split model layers across GPUs to pipeline compute (e.g., while one GPU computes later layers for Request A, another starts early layers for Request B).
  • +
+

6. Speculative Decoding

+

To reduce inter-token latency (ITL), we explore speculative decoding.

+
    +
  • Mechanism: A smaller, faster "draft" model speculatively generates a short token sequence (e.g., 5 tokens).
  • +
  • Verification: The larger target model verifies those tokens in one parallel forward pass. If correct, we effectively generate multiple tokens per large-model step; if not, we discard and regenerate. This is effective for predictable text, improving perceived generation speed.
  • +
+

Few Benchmarks

+

Below are a couple of representative use cases and performance numbers.

+

Search query rewriting

+
    +
  • LLM: Fine-tuned llama-3.2-1B
  • +
  • Input & output token length: ~10–20
  • +
  • Response type: Non-streaming
  • +
+
Inference runtimeHardwareMax requests/secMax p99 latency
TensorRT-LLM4 × L4 GPUs (multi-GPU)100095 ms
TensorRT-LLM1 × A100 40 GB GPU100069 ms
+

Voice bot query

+
    +
  • LLM: Llama-3.1-8B
  • +
  • Input token length: ~1900–2000
  • +
  • Output token length: ~200
  • +
  • Response type: Streaming
  • +
+
Inference runtimeConcurrencyp99 TTFT (ms)p99 ITL (ms)Token throughput (tokens/sec)Request throughput (req/sec)Hardware
TensorRT-LLM136.2722.7845.660.23L4
TensorRT-LLM249.8123.2189.370.45L4
TensorRT-LLM455.3336.62153.390.78L4
TensorRT-LLM866.539.11279.881.47L4
TensorRT-LLM16131.830.39547.82.77L4
TensorRT-LLM32277.2248.02925.74.78L4
TensorRT-LLM64498.5271.621,164.406.2L4
TensorRT-LLM128677.31120.371,445.187.69L4
TensorRT-LLM2561,926.31216.881,600.818.52L4
TensorRT-LLM121.179.24130.050.68A100
TensorRT-LLM225.789.21264.51.35A100
TensorRT-LLM428.5210.99437.692.27A100
TensorRT-LLM834.412.61760.493.96A100
TensorRT-LLM1668.0314.321,343.807.01A100
TensorRT-LLM32185.9616.822,287.3011.92A100
TensorRT-LLM64136.8721.173,625.2218.89A100
TensorRT-LLM128463.7834.154,456.5123.24A100
TensorRT-LLM256890.1259.185,188.2427.05A100
+

Conclusion

+

High-performance LLM inference is fundamentally a systems engineering problem: memory efficiency, kernel execution, batching strategy, and parallelism determine real-world latency and throughput. Techniques such as paged KV caching, aggressive quantization, kernel fusion, and inflight batching improve GPU utilization while reducing latency and memory pressure.

+

These optimizations enable the platform to deliver sub-second responses, sustain high concurrency, and efficiently serve both lightweight and long-context workloads. By continuously optimizing across the full inference stack, we keep LLM serving scalable, cost-efficient, and production-ready for real-time AI applications.

]]>
+ + Jaya Kumar + https://github.com/jayakommuru + + + + + + + +
+ + <![CDATA[Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving]]> + https://meesho.github.io/BharatMLStack/blog/post-three + + 2025-03-29T00:00:00.000Z + + BharatMLStack

+

Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving

+

Serving large language models in production introduces new challenges across infrastructure, performance optimization, and operational lifecycle management. The LLM Inference Platform addresses these challenges by providing a unified system for deploying and managing open-source and fine-tuned LLMs at scale.

+

The platform implements a complete LLMOps lifecycle — from model registration and automated compilation to deployment, runtime optimization, and monitoring. Designed as a self-service environment, users can onboard models directly from open repositories such as Hugging Face or upload custom fine-tuned models, and deploy them using a single-click workflow with no manual infrastructure or configuration steps required.

+

In addition to fully automated deployment, the platform allows users to select and apply custom inference optimization techniques — such as quantization strategies, batching configurations, and runtime-specific performance enhancements — enabling teams to balance latency, throughput, and cost based on their use case. The goal is to reduce operational friction while enabling high-performance, production-grade LLM inference.

+

Why LLM Inference Is not just bigger ML model serving

+

Large language model (LLM) inference introduces a fundamentally different set of challenges compared to traditional machine learning inference. While classical ML models typically perform a single forward pass to produce a fixed prediction, LLMs operate as autoregressive systems, generating outputs token by token based on previously generated context. This difference dramatically changes how inference systems must be designed, optimized, and scaled.

+

Autoregressive Generation and Sequential Computation:

+

Unlike traditional models such as classifiers or recommenders — where inference cost is relatively constant — LLMs generate responses incrementally. Each new token depends on all previously generated tokens, making inference inherently sequential and dynamic. This means latency and compute requirements vary significantly depending on prompt length and output size, introducing complexity in scheduling and resource allocation. +Because tokens cannot be generated fully in parallel during decoding, GPUs may become underutilized without specialized batching and scheduling strategies. This has led to the development of dedicated LLM inference engines optimized for token-level execution.

+

Prefill and Decode Phases:

+

LLM inference typically consists of two distinct stages:

+
    +
  • Prefill phase — the model processes the input prompt and builds internal representations. This stage is compute-heavy and highly parallelizable.
  • +
  • Decode phase — the model generates tokens sequentially, predicting one token at a time using previously generated context.
  • +
+

The decode stage often becomes memory-bound rather than compute-bound, which creates new performance bottlenecks compared to traditional ML workloads.

+

Context Management and KV Caching:

+

Another fundamental difference lies in how LLMs maintain context. Transformer-based models rely on attention mechanisms that require access to past token representations. To avoid recomputing these representations repeatedly, inference engines use key-value (KV) caching, which stores intermediate activations from previous tokens. +KV caching significantly improves performance by eliminating redundant computation, but it introduces new challenges:

+
    +
  • Memory consumption grows with sequence length and batch size
  • +
  • GPU memory becomes a critical bottleneck
  • +
  • Efficient memory management becomes essential for scaling concurrent requests
  • +
+

This tradeoff between compute efficiency and memory usage is unique to LLM inference workloads.

+

Dynamic and Irregular Workloads:

+

Traditional ML inference typically operates on fixed-size inputs with predictable latency. In contrast, LLM requests vary widely in prompt length, output length, and runtime behavior. As a result:

+
    +
  • Batch sizes must be dynamic rather than static
  • +
  • Requests may enter and leave batches asynchronously
  • +
  • Scheduling systems must continuously rebalance workloads to maximize GPU utilization
  • +
+

These characteristics require specialized serving architectures that differ significantly from standard ML serving pipelines.

+

Streaming and User Experience Constraints:

+

Another distinguishing factor is the expectation of real-time streaming responses. Instead of returning a single output, LLM systems often stream tokens to users as they are generated. +Because of these differences — sequential generation, growing memory requirements, dynamic workloads, and streaming constraints — LLM inference cannot be treated as a simple extension of existing ML serving systems. Production platforms must incorporate specialized runtime engines, advanced optimization techniques, and observability tailored specifically to LLM workloads.

+

LLMOps: High-Level Architecture

+

LLM Architecture

+

The LLM Inference Framework is designed as a fully automated, end-to-end system for deploying and operating open-source and fine-tuned large language models at scale. The architecture abstracts the complexity of model optimization, hardware selection, deployment, and runtime management into a unified workflow that enables users to move from raw model weights to production-ready inference endpoints with minimal manual intervention.

+

Our LLM Inference Framework is architected not just as a serving engine, but as a complete lifecycle management system. As illustrated in the high-level design below, the platform automates the journey of a model through seven distinct stages, ensuring reproducibility, performance, and scalability.

+
    +
  1. +

    Onboarding & Registration (The Source of Truth)

    +

    The lifecycle begins with the Data Scientist or engineer.

    +
      +
    • Model Ingestion: Users onboard models—whether open-source (Hugging Face, NeMo) or internally fine-tuned—via the Truffle Box SDK/UI.
    • +
    • LLM + Prompt Registry: Unlike traditional systems that only track model weights, our registry is a unified control plane. It stores both the Model Artifacts and the Prompt Templates. This allows Data Scientists to register and version-control prompts (e.g., "customer_support_v2") independently of the application code.
    • +
    +
  2. +
  3. +

    The "Black Box" Build Engine

    +

    Once a model is registered, the Automated LLM Compiler + Quantizer Module kicks off a background job on ephemeral GPU resources.

    +
      +
    • Transformation: The raw model is converted into a TRT-LLM Checkpoint.
    • +
    • Quantization: The system automatically applies quantization algorithms (like INT4 AWQ or FP8) to reduce memory footprint.
    • +
    • Engine Building: Finally, it compiles a highly optimized TRT Engine specifically tuned for the target hardware.
    • +
    +
  4. +
  5. +

    Intelligent Profiling & Validation

    +

    Before deployment, the new engine passes through the Hardware & Inference Runtime Profiler.

    +
      +
    • Benchmarking: This module empirically tests the engine against various hardware configurations (L4 vs. A100) and runtimes (TRT-LLM vs. vLLM).
    • +
    • Optimization: It recommends the optimal configuration that meets latency SLAs (Time-To-First-Token) while minimizing cost.
    • +
    +
  6. +
  7. +

    Smart Artifact Generation & Distribution

    +

    To solve the Kubernetes "Cold Start" problem, the LLM Serving Artifacts Generation module packages the model using a bifurcated strategy:

    +
      +
    • Standard Models: Artifacts are uploaded to Cloud Storage (GCS) and downloaded by pods at startup.
    • +
    • Very Large Models: For massive models (>8GB) where network downloads are too slow, the system pre-caches the model onto Secondary Boot Disks. These disks are attached directly to new GPU nodes during autoscaling, eliminating download wait times.
    • +
    +
  8. +
  9. +

    Image Streaming & Deployment

    +

    Simultaneously, the inference runtime container images are pulled from the Artifact Registry.

    +
      +
    • Image Streaming: We utilize container image streaming to allow pods to start initializing while the massive Triton/Dynamo container layers are still downloading, further shaving seconds off the startup time. link
    • +
    +
  10. +
  11. +

    The Inference Runtime (Kubernetes)

    +

    The workload lands on Kubernetes with Autoscaling.

    +
      +
    • Dynamic Backends: Depending on the profile generated in Stage 3, the pod initializes either TensorRT-LLM (for throughput) or vLLM (for flexibility), or spins up a Dynamo worker for distributed inference.
    • +
    • Data Loading: The pod either downloads the model from Cloud Storage or mounts the pre-warmed Secondary Boot Disk ("Pull from Disk").
    • +
    +
  12. +
  13. +

    Client Interaction & Observability

    +

    Finally, the LLM Inference Client executes the request.

    +
      +
    • Prompt Injection: The client pulls the specific prompt template ID from the Registry, ensuring the exact versioned instructions are used.
    • +
    • Streaming Response: The request is sent via gRPC, and tokens are streamed back to the user in real-time.
    • +
    +
  14. +
  15. +

    Observability: Monitoring the Pulse of GenAI

    +

    In traditional microservices, success is measured by CPU utilization and request latency (p99). For Large Language Models, these metrics are insufficient. A user doesn't care if the GPU is at 80% utilization; they care about how fast the first word appears and how smoothly the rest of the sentence follows.

    +

    To capture the true user experience, our platform instrumentation focuses on three critical LLM-specific metrics:

    +
      +
    1. +

      Time to First Token (TTFT)

      +
        +
      • Definition: TTFT measures the time elapsed from the moment a request is received until the very first token is generated and streamed back to the user.
      • +
      • Why it matters: This represents the "Prefill Phase" latency—the time the model takes to process the input prompt and load weights. A high TTFT makes the application feel unresponsive or "hung."
      • +
      • Optimization: We closely monitor TTFT to ensure our Prefix Caching is effective (aiming for high cache hitrates), which drastically lowers this metric by skipping redundant prompt processing.
      • +
      +
    2. +
    3. +

      Inter-Token Latency (ITL)

      +
        +
      • Definition: ITL measures the average time interval between the generation of consecutive tokens during the "Decode Phase".
      • +
      • Why it matters: This defines the "perceived speed" of reading. Even if the first token is fast (low TTFT), high ITL makes the text generation look "jerky" or slow to the user.
      • +
      • Benchmarks: In our testing with Llama 3.1, we track p99 ITL to ensure it stays below human reading speeds to maintain a natural conversational flow.
      • +
      +
    4. +
    5. +

      Token Throughput vs. Request Throughput

      +
        +
      • We distinguish between two types of throughput to balance system efficiency with user load:
      • +
      • Token Throughput (tokens/sec): The total number of tokens generated across all concurrent requests. This measures the raw compute efficiency of the GPU and the effectiveness of batching.
      • +
      • Request Throughput (req/sec): The number of distinct user queries served per second. We use this to determine autoscaling thresholds, ensuring we scale out before the queue depth impacts ITL.
      • +
      +
    6. +
    7. +

      The Monitoring Stack

      +
        +
      • Real-time Dashboards: We utilize Grafana to visualize these streaming metrics in real-time, allowing on-call engineers to spot "slow generation" incidents that generic "500 error" alerts would miss.
      • +
      • Request Tracing: Since Triton Inference Server does not log request payloads by default, we integrate a Helix Client to asynchronously publish request logs to Log Tables. This allows us to trace a specific "slow" request back to its prompt to understand if a complex input caused the latency spike.
      • +
      +
    8. +
    +
  16. +
+

Supported Inference backends (TensorRT LLM, Dynamo & vLLM)

+

Tailored for the Use Case: We do not believe in a "one-size-fits-all" approach to inference. Different use cases—whether a real-time voice bot requiring ultra-lowsub-second latency or a massive reasoning task requiring huge context windows—demand different runtime characteristics. Our platform is designed to be runtime-agnostic, allowing us to automatically select and tailor the best engine based on the specific requirements of the application:

+
    +
  1. +

    TensorRT-LLM: The High-Performance Standard

    +

    Suitable for: High-throughput production workloads where latency is critical (e.g., customer support chat, real-time voice bots).

    +

    TensorRT-LLM serves as our default backend for these scenarios. Our internal benchmarks on Llama 3.1 and 3.2 models demonstrated that a tuned TensorRT-LLM engine significantly outperforms standard runtimes, especially when utilizing INT4 AWQ and FP8 quantization .

    +

    Key optimizations we tailor for these high-load cases include:

    +
      +
    • Optimized execution via TensorRT engine compilation
    • +
    • Quantization-aware execution for reduced memory usage and improved throughput
    • +
    • Inflight Batching: Allowing requests to be processed continuously without waiting for the entire batch to finish, drastically improving GPU utilization .
    • +
    • Custom Plugins: Enabling specific NVIDIA plugins like the GEMM plugin and GPT Attention plugin to accelerate matrix multiplications and attention mechanisms .
    • +
    +
  2. +
  3. +

    Dynamo: Distributed Inference for Reasoning Models

    +

    Suitable for: Very large "reasoning" models (70B+) or scenarios requiring massive context windows where a single GPU's memory is insufficient.

    +

    For these memory-bound tasks, we utilize Dynamo, a low-latency distributed inference framework . Unlike monolithic servers, Dynamo disaggregates the inference process to scale resources horizontally:

    +
      +
    • KV Aware Routing: A specialized router directs requests to workers that already hold the relevant Key-Value (KV) cache, minimizing redundant computation .
    • +
    • Prefill vs. Decode Split: The workload is divided into Prefill Workers (processing the prompt) and Decode Workers (generating tokens), allowing us to scale the compute-heavy "reading" phase independently from the memory-heavy "writing" phase .
    • +
    • Distributed execution across multiple GPU resources
    • +
    +
  4. +
  5. +

    vLLM: The Flexible Baseline

    +

    Suitable for: Rapid prototyping, testing new model architectures, or low-traffic internal tools where ease of deployment outweighs raw throughput.

    +

    While TensorRT-LLM is optimized for maximum speed, vLLM provides a robust and flexible baseline .

    +
      +
    • High throughput through dynamic batching and efficient memory utilization
    • +
    • Paged KV cache management for handling long contexts and concurrent requests
    • +
    • Strong support for open-source model ecosystems
    • +
    • Rapid Adoption: It allows us to onboard new model architectures immediately without waiting for a custom TensorRT build.
    • +
    • Benchmarking Insight: In our internal tests, vLLM provided a strong baseline but often lacked the specific max-token optimizations present in our custom TRT engines . We use it strategically for initial testing before committing to a full TensorRT optimization pipeline.
    • +
    +
  6. +
+

Conclusion

+

Large language model inference introduces a fundamentally new class of infrastructure challenges—where performance is governed not just by raw compute, but by memory efficiency, intelligent scheduling, runtime specialization, and lifecycle automation. Unlike traditional ML serving, LLM inference requires systems that understand token-level execution, manage rapidly growing context state, and continuously balance latency, throughput, and cost under highly dynamic workloads.

+

The LLM Inference Framework addresses these challenges by transforming inference into a fully automated, reproducible lifecycle—from model onboarding and compilation to deployment, optimization, and observability. By integrating automated quantization and engine compilation, intelligent runtime selection, cold-start mitigation strategies, and LLM-specific observability metrics such as Time-to-First-Token and Inter-Token Latency, the platform ensures both high performance and operational simplicity.

+

Equally important, the framework is designed with flexibility and future evolution in mind. Its runtime-agnostic architecture enables seamless adoption of emerging inference engines, hardware accelerators, and optimization techniques without requiring platform redesign. This ensures that teams can continuously leverage advancements in the rapidly evolving LLM ecosystem while maintaining consistent operational workflows.

+

Ultimately, the goal of the platform is to make production-scale LLM deployment as seamless and reliable as traditional software deployment—allowing teams to focus on building intelligent applications rather than managing infrastructure complexity. By combining lifecycle automation, runtime optimization, and deep observability, the LLM Inference Framework provides a scalable foundation for delivering fast, cost-efficient, and production-ready LLM experiences.

+

Future Explorations

+

While we have achieved significant milestones in latency and throughput, the landscape of GenAI is evolving rapidly. Our roadmap focuses on increasing flexibility, reducing costs, and enhancing reliability for enterprise-grade workloads. Here is what we are building next:

+
    +
  • TPU Support: To diversify our hardware supply chain and further optimize cost-per-token, we are evaluating Google Cloud TPUs to bake it into our platform. By leveraging the JAX and PyTorch/XLA ecosystems, we aim to unlock the massive throughput potential of TPU v5e chips, particularly for our open-source Llama models. This will allow the hardware profiler to dynamically choose between NVIDIA GPUs and Google TPUs based on real-time availability and price-performance metrics.
  • +
  • Multi-LoRA Serving (Serverless Experience): Currently, deploying a fine-tuned model requires a dedicated GPU. We are building support for Multi-LoRA serving, which will allow us to serve hundreds of unique, fine-tuned adapters on top of a single frozen base model. This will drastically reduce costs for multi-tenant applications, enabling a "serverless" experience where specific fine-tunes are hot-swapped instantly per request.
  • +
  • Spot Instance Orchestration: To further optimize cloud costs, we are developing fault-tolerant mechanisms to run inference workloads on Spot Instances. By implementing aggressive checkpointing and seamless request draining, we aim to leverage cheaper, preemptible compute capacity without interrupting the user's streaming experience.
  • +
  • Semantic Caching Layer: We plan to move beyond standard Prefix Caching to implement Semantic Caching. By using a vector database to fetch responses for semantically similar queries (e.g., "How do I reset my password?" vs. "Password reset steps"), we can bypass the GPU entirely for repetitive queries, reducing latency to near-zero.
  • +
  • Context-Aware Autoscaling: Standard CPU/GPU utilization metrics are often insufficient signals for scaling LLMs. We are working on KV-cache pressure metrics for autoscaling. This ensures that we scale out before the memory fills up, preventing eviction-based slowdowns during traffic spikes.
  • +
  • Online Evaluation & Guardrails: We are integrating a lightweight "Trust Layer" into the proxy. This will allow for low-latency input/output filtering (Guardrails) and asynchronous "LLM-as-a-Judge" evaluation pipelines to monitor response quality in production, not just system health.
  • +
]]>
+ + Jaya Kumar + https://github.com/jayakommuru + + + + + + + +
+ + <![CDATA[Cracking the Code: Scaling Model Inference & Real-Time Embedding Search]]> + https://meesho.github.io/BharatMLStack/blog/post-three + + 2024-05-21T00:00:00.000Z + + BharatMLStack

+

Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving

+

Serving large language models in production introduces new challenges across infrastructure, performance optimization, and operational lifecycle management. The LLM Inference Platform addresses these challenges by providing a unified system for deploying and managing open-source and fine-tuned LLMs at scale.

+

The platform implements a complete LLMOps lifecycle — from model registration and automated compilation to deployment, runtime optimization, and monitoring. Designed as a self-service environment, users can onboard models directly from open repositories such as Hugging Face or upload custom fine-tuned models, and deploy them using a single-click workflow with no manual infrastructure or configuration steps required.

+

In addition to fully automated deployment, the platform allows users to select and apply custom inference optimization techniques — such as quantization strategies, batching configurations, and runtime-specific performance enhancements — enabling teams to balance latency, throughput, and cost based on their use case. The goal is to reduce operational friction while enabling high-performance, production-grade LLM inference.

+

Why LLM Inference Is not just bigger ML model serving

+

Large language model (LLM) inference introduces a fundamentally different set of challenges compared to traditional machine learning inference. While classical ML models typically perform a single forward pass to produce a fixed prediction, LLMs operate as autoregressive systems, generating outputs token by token based on previously generated context. This difference dramatically changes how inference systems must be designed, optimized, and scaled.

+

Autoregressive Generation and Sequential Computation:

+

Unlike traditional models such as classifiers or recommenders — where inference cost is relatively constant — LLMs generate responses incrementally. Each new token depends on all previously generated tokens, making inference inherently sequential and dynamic. This means latency and compute requirements vary significantly depending on prompt length and output size, introducing complexity in scheduling and resource allocation. +Because tokens cannot be generated fully in parallel during decoding, GPUs may become underutilized without specialized batching and scheduling strategies. This has led to the development of dedicated LLM inference engines optimized for token-level execution.

+

Prefill and Decode Phases:

+

LLM inference typically consists of two distinct stages:

+
    +
  • Prefill phase — the model processes the input prompt and builds internal representations. This stage is compute-heavy and highly parallelizable.
  • +
  • Decode phase — the model generates tokens sequentially, predicting one token at a time using previously generated context.
  • +
+

The decode stage often becomes memory-bound rather than compute-bound, which creates new performance bottlenecks compared to traditional ML workloads.

+

Context Management and KV Caching:

+

Another fundamental difference lies in how LLMs maintain context. Transformer-based models rely on attention mechanisms that require access to past token representations. To avoid recomputing these representations repeatedly, inference engines use key-value (KV) caching, which stores intermediate activations from previous tokens. +KV caching significantly improves performance by eliminating redundant computation, but it introduces new challenges:

+
    +
  • Memory consumption grows with sequence length and batch size
  • +
  • GPU memory becomes a critical bottleneck
  • +
  • Efficient memory management becomes essential for scaling concurrent requests
  • +
+

This tradeoff between compute efficiency and memory usage is unique to LLM inference workloads.

+

Dynamic and Irregular Workloads:

+

Traditional ML inference typically operates on fixed-size inputs with predictable latency. In contrast, LLM requests vary widely in prompt length, output length, and runtime behavior. As a result:

+
    +
  • Batch sizes must be dynamic rather than static
  • +
  • Requests may enter and leave batches asynchronously
  • +
  • Scheduling systems must continuously rebalance workloads to maximize GPU utilization
  • +
+

These characteristics require specialized serving architectures that differ significantly from standard ML serving pipelines.

+

Streaming and User Experience Constraints:

+

Another distinguishing factor is the expectation of real-time streaming responses. Instead of returning a single output, LLM systems often stream tokens to users as they are generated. +Because of these differences — sequential generation, growing memory requirements, dynamic workloads, and streaming constraints — LLM inference cannot be treated as a simple extension of existing ML serving systems. Production platforms must incorporate specialized runtime engines, advanced optimization techniques, and observability tailored specifically to LLM workloads.

+

LLMOps: High-Level Architecture

+

LLM Architecture

+

The LLM Inference Framework is designed as a fully automated, end-to-end system for deploying and operating open-source and fine-tuned large language models at scale. The architecture abstracts the complexity of model optimization, hardware selection, deployment, and runtime management into a unified workflow that enables users to move from raw model weights to production-ready inference endpoints with minimal manual intervention.

+

Our LLM Inference Framework is architected not just as a serving engine, but as a complete lifecycle management system. As illustrated in the high-level design below, the platform automates the journey of a model through seven distinct stages, ensuring reproducibility, performance, and scalability.

+
    +
  1. +

    Onboarding & Registration (The Source of Truth)

    +

    The lifecycle begins with the Data Scientist or engineer.

    +
      +
    • Model Ingestion: Users onboard models—whether open-source (Hugging Face, NeMo) or internally fine-tuned—via the Truffle Box SDK/UI.
    • +
    • LLM + Prompt Registry: Unlike traditional systems that only track model weights, our registry is a unified control plane. It stores both the Model Artifacts and the Prompt Templates. This allows Data Scientists to register and version-control prompts (e.g., "customer_support_v2") independently of the application code.
    • +
    +
  2. +
  3. +

    The "Black Box" Build Engine

    +

    Once a model is registered, the Automated LLM Compiler + Quantizer Module kicks off a background job on ephemeral GPU resources.

    +
      +
    • Transformation: The raw model is converted into a TRT-LLM Checkpoint.
    • +
    • Quantization: The system automatically applies quantization algorithms (like INT4 AWQ or FP8) to reduce memory footprint.
    • +
    • Engine Building: Finally, it compiles a highly optimized TRT Engine specifically tuned for the target hardware.
    • +
    +
  4. +
  5. +

    Intelligent Profiling & Validation

    +

    Before deployment, the new engine passes through the Hardware & Inference Runtime Profiler.

    +
      +
    • Benchmarking: This module empirically tests the engine against various hardware configurations (L4 vs. A100) and runtimes (TRT-LLM vs. vLLM).
    • +
    • Optimization: It recommends the optimal configuration that meets latency SLAs (Time-To-First-Token) while minimizing cost.
    • +
    +
  6. +
  7. +

    Smart Artifact Generation & Distribution

    +

    To solve the Kubernetes "Cold Start" problem, the LLM Serving Artifacts Generation module packages the model using a bifurcated strategy:

    +
      +
    • Standard Models: Artifacts are uploaded to Cloud Storage (GCS) and downloaded by pods at startup.
    • +
    • Very Large Models: For massive models (>8GB) where network downloads are too slow, the system pre-caches the model onto Secondary Boot Disks. These disks are attached directly to new GPU nodes during autoscaling, eliminating download wait times.
    • +
    +
  8. +
  9. +

    Image Streaming & Deployment

    +

    Simultaneously, the inference runtime container images are pulled from the Artifact Registry.

    +
      +
    • Image Streaming: We utilize container image streaming to allow pods to start initializing while the massive Triton/Dynamo container layers are still downloading, further shaving seconds off the startup time. link
    • +
    +
  10. +
  11. +

    The Inference Runtime (Kubernetes)

    +

    The workload lands on Kubernetes with Autoscaling.

    +
      +
    • Dynamic Backends: Depending on the profile generated in Stage 3, the pod initializes either TensorRT-LLM (for throughput) or vLLM (for flexibility), or spins up a Dynamo worker for distributed inference.
    • +
    • Data Loading: The pod either downloads the model from Cloud Storage or mounts the pre-warmed Secondary Boot Disk ("Pull from Disk").
    • +
    +
  12. +
  13. +

    Client Interaction & Observability

    +

    Finally, the LLM Inference Client executes the request.

    +
      +
    • Prompt Injection: The client pulls the specific prompt template ID from the Registry, ensuring the exact versioned instructions are used.
    • +
    • Streaming Response: The request is sent via gRPC, and tokens are streamed back to the user in real-time.
    • +
    +
  14. +
  15. +

    Observability: Monitoring the Pulse of GenAI

    +

    In traditional microservices, success is measured by CPU utilization and request latency (p99). For Large Language Models, these metrics are insufficient. A user doesn't care if the GPU is at 80% utilization; they care about how fast the first word appears and how smoothly the rest of the sentence follows.

    +

    To capture the true user experience, our platform instrumentation focuses on three critical LLM-specific metrics:

    +
      +
    1. +

      Time to First Token (TTFT)

      +
        +
      • Definition: TTFT measures the time elapsed from the moment a request is received until the very first token is generated and streamed back to the user.
      • +
      • Why it matters: This represents the "Prefill Phase" latency—the time the model takes to process the input prompt and load weights. A high TTFT makes the application feel unresponsive or "hung."
      • +
      • Optimization: We closely monitor TTFT to ensure our Prefix Caching is effective (aiming for high cache hitrates), which drastically lowers this metric by skipping redundant prompt processing.
      • +
      +
    2. +
    3. +

      Inter-Token Latency (ITL)

      +
        +
      • Definition: ITL measures the average time interval between the generation of consecutive tokens during the "Decode Phase".
      • +
      • Why it matters: This defines the "perceived speed" of reading. Even if the first token is fast (low TTFT), high ITL makes the text generation look "jerky" or slow to the user.
      • +
      • Benchmarks: In our testing with Llama 3.1, we track p99 ITL to ensure it stays below human reading speeds to maintain a natural conversational flow.
      • +
      +
    4. +
    5. +

      Token Throughput vs. Request Throughput

      +
        +
      • We distinguish between two types of throughput to balance system efficiency with user load:
      • +
      • Token Throughput (tokens/sec): The total number of tokens generated across all concurrent requests. This measures the raw compute efficiency of the GPU and the effectiveness of batching.
      • +
      • Request Throughput (req/sec): The number of distinct user queries served per second. We use this to determine autoscaling thresholds, ensuring we scale out before the queue depth impacts ITL.
      • +
      +
    6. +
    7. +

      The Monitoring Stack

      +
        +
      • Real-time Dashboards: We utilize Grafana to visualize these streaming metrics in real-time, allowing on-call engineers to spot "slow generation" incidents that generic "500 error" alerts would miss.
      • +
      • Request Tracing: Since Triton Inference Server does not log request payloads by default, we integrate a Helix Client to asynchronously publish request logs to Log Tables. This allows us to trace a specific "slow" request back to its prompt to understand if a complex input caused the latency spike.
      • +
      +
    8. +
    +
  16. +
+

Supported Inference backends (TensorRT LLM, Dynamo & vLLM)

+

Tailored for the Use Case: We do not believe in a "one-size-fits-all" approach to inference. Different use cases—whether a real-time voice bot requiring ultra-lowsub-second latency or a massive reasoning task requiring huge context windows—demand different runtime characteristics. Our platform is designed to be runtime-agnostic, allowing us to automatically select and tailor the best engine based on the specific requirements of the application:

+
    +
  1. +

    TensorRT-LLM: The High-Performance Standard

    +

    Suitable for: High-throughput production workloads where latency is critical (e.g., customer support chat, real-time voice bots).

    +

    TensorRT-LLM serves as our default backend for these scenarios. Our internal benchmarks on Llama 3.1 and 3.2 models demonstrated that a tuned TensorRT-LLM engine significantly outperforms standard runtimes, especially when utilizing INT4 AWQ and FP8 quantization .

    +

    Key optimizations we tailor for these high-load cases include:

    +
      +
    • Optimized execution via TensorRT engine compilation
    • +
    • Quantization-aware execution for reduced memory usage and improved throughput
    • +
    • Inflight Batching: Allowing requests to be processed continuously without waiting for the entire batch to finish, drastically improving GPU utilization .
    • +
    • Custom Plugins: Enabling specific NVIDIA plugins like the GEMM plugin and GPT Attention plugin to accelerate matrix multiplications and attention mechanisms .
    • +
    +
  2. +
  3. +

    Dynamo: Distributed Inference for Reasoning Models

    +

    Suitable for: Very large "reasoning" models (70B+) or scenarios requiring massive context windows where a single GPU's memory is insufficient.

    +

    For these memory-bound tasks, we utilize Dynamo, a low-latency distributed inference framework . Unlike monolithic servers, Dynamo disaggregates the inference process to scale resources horizontally:

    +
      +
    • KV Aware Routing: A specialized router directs requests to workers that already hold the relevant Key-Value (KV) cache, minimizing redundant computation .
    • +
    • Prefill vs. Decode Split: The workload is divided into Prefill Workers (processing the prompt) and Decode Workers (generating tokens), allowing us to scale the compute-heavy "reading" phase independently from the memory-heavy "writing" phase .
    • +
    • Distributed execution across multiple GPU resources
    • +
    +
  4. +
  5. +

    vLLM: The Flexible Baseline

    +

    Suitable for: Rapid prototyping, testing new model architectures, or low-traffic internal tools where ease of deployment outweighs raw throughput.

    +

    While TensorRT-LLM is optimized for maximum speed, vLLM provides a robust and flexible baseline .

    +
      +
    • High throughput through dynamic batching and efficient memory utilization
    • +
    • Paged KV cache management for handling long contexts and concurrent requests
    • +
    • Strong support for open-source model ecosystems
    • +
    • Rapid Adoption: It allows us to onboard new model architectures immediately without waiting for a custom TensorRT build.
    • +
    • Benchmarking Insight: In our internal tests, vLLM provided a strong baseline but often lacked the specific max-token optimizations present in our custom TRT engines . We use it strategically for initial testing before committing to a full TensorRT optimization pipeline.
    • +
    +
  6. +
+

Conclusion

+

Large language model inference introduces a fundamentally new class of infrastructure challenges—where performance is governed not just by raw compute, but by memory efficiency, intelligent scheduling, runtime specialization, and lifecycle automation. Unlike traditional ML serving, LLM inference requires systems that understand token-level execution, manage rapidly growing context state, and continuously balance latency, throughput, and cost under highly dynamic workloads.

+

The LLM Inference Framework addresses these challenges by transforming inference into a fully automated, reproducible lifecycle—from model onboarding and compilation to deployment, optimization, and observability. By integrating automated quantization and engine compilation, intelligent runtime selection, cold-start mitigation strategies, and LLM-specific observability metrics such as Time-to-First-Token and Inter-Token Latency, the platform ensures both high performance and operational simplicity.

+

Equally important, the framework is designed with flexibility and future evolution in mind. Its runtime-agnostic architecture enables seamless adoption of emerging inference engines, hardware accelerators, and optimization techniques without requiring platform redesign. This ensures that teams can continuously leverage advancements in the rapidly evolving LLM ecosystem while maintaining consistent operational workflows.

+

Ultimately, the goal of the platform is to make production-scale LLM deployment as seamless and reliable as traditional software deployment—allowing teams to focus on building intelligent applications rather than managing infrastructure complexity. By combining lifecycle automation, runtime optimization, and deep observability, the LLM Inference Framework provides a scalable foundation for delivering fast, cost-efficient, and production-ready LLM experiences.

+

Future Explorations

+

While we have achieved significant milestones in latency and throughput, the landscape of GenAI is evolving rapidly. Our roadmap focuses on increasing flexibility, reducing costs, and enhancing reliability for enterprise-grade workloads. Here is what we are building next:

+
    +
  • TPU Support: To diversify our hardware supply chain and further optimize cost-per-token, we are evaluating Google Cloud TPUs to bake it into our platform. By leveraging the JAX and PyTorch/XLA ecosystems, we aim to unlock the massive throughput potential of TPU v5e chips, particularly for our open-source Llama models. This will allow the hardware profiler to dynamically choose between NVIDIA GPUs and Google TPUs based on real-time availability and price-performance metrics.
  • +
  • Multi-LoRA Serving (Serverless Experience): Currently, deploying a fine-tuned model requires a dedicated GPU. We are building support for Multi-LoRA serving, which will allow us to serve hundreds of unique, fine-tuned adapters on top of a single frozen base model. This will drastically reduce costs for multi-tenant applications, enabling a "serverless" experience where specific fine-tunes are hot-swapped instantly per request.
  • +
  • Spot Instance Orchestration: To further optimize cloud costs, we are developing fault-tolerant mechanisms to run inference workloads on Spot Instances. By implementing aggressive checkpointing and seamless request draining, we aim to leverage cheaper, preemptible compute capacity without interrupting the user's streaming experience.
  • +
  • Semantic Caching Layer: We plan to move beyond standard Prefix Caching to implement Semantic Caching. By using a vector database to fetch responses for semantically similar queries (e.g., "How do I reset my password?" vs. "Password reset steps"), we can bypass the GPU entirely for repetitive queries, reducing latency to near-zero.
  • +
  • Context-Aware Autoscaling: Standard CPU/GPU utilization metrics are often insufficient signals for scaling LLMs. We are working on KV-cache pressure metrics for autoscaling. This ensures that we scale out before the memory fills up, preventing eviction-based slowdowns during traffic spikes.
  • +
  • Online Evaluation & Guardrails: We are integrating a lightweight "Trust Layer" into the proxy. This will allow for low-latency input/output filtering (Guardrails) and asynchronous "LLM-as-a-Judge" evaluation pipelines to monitor response quality in production, not just system health.
  • +
]]>
+ + Aditya Kumar + https://github.com/Adit2607 + + + Jaya Kumar + https://github.com/jayakommuru + + + Adarsha Das + https://github.com/a0d00kc + + + + + + +
+ + <![CDATA[Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)]]> + https://meesho.github.io/BharatMLStack/blog/post-two + + 2023-04-10T00:00:00.000Z + + BharatMLStack

+

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

+

By late 2022, we had built something we were truly proud of—a real-time ML serving system with a DAG-based executor, a feature store, and an interaction store powering key ranking and personalization models. It was a major milestone, the culmination of months of effort from data scientists, ML engineers, and backend teams. Our system was live, and we were ready to push the boundaries of experimentation. +And it worked. Mostly. +But soon, cracks appeared. Every new model needed custom feature retrieval logic, DAGs became dense and unmanageable, and scaling turned into a constant firefight. Costs surged, and infra bottlenecks slowed experimentation. Our system worked, but it wasn’t built for scale. +This is the story of how we tackled these challenges—building Inferflow for seamless feature retrieval, optimizing real-time infra, and cutting costs while scaling to millions of QPS.

+

The Cost of Success

+

Every new Ranker model required its own feature set, often pulling from different entities. Each addition meant:

+
    +
  • Adding new DAG nodes in IOP
  • +
  • Writing custom logic to fetch features from multiple sources (e.g., user, product, user × category)
  • +
  • Inferring intermediate features (e.g., extracting category from a product to fetch user × category data)
  • +
  • Optimizing I/O and dealing with the inevitable bugs
  • +
+

What began as clean DAGs soon turned into a tangled web of cross-dependent graphs. Every experimentation cycle meant new nodes, new dependencies, and slower iterations.

+

Scaling Pains (and Cassandra’s Limits)

+

At some point, we were hitting:

+
    +
  • 250–300K reads/sec
  • +
  • 1M writes/sec (during lean hours)
  • +
+

All of this ran on Cassandra. While its distributed architecture had been proven in production, operating large-scale clusters came with considerable infrastructure overhead. Our proof-of-concept (POC) demonstrated throughput of around 100K ops/sec, but as we scaled further, the challenges grew. Ensuring node health, optimizing compaction, and maintaining storage balance became increasingly demanding. We also observed latency spikes under heavy load, alongside a sharp increase in total cost of ownership.

+

Interaction Store Woes

+

Our interaction store was another ticking time bomb:

+
    +
  • 🚨 Clusters kept growing in size and cost
  • +
  • 🚨 Latency spikes became increasingly frequent
  • +
  • 🚨 The DMC proxy occasionally lost locality of nodes against shards, causing cross-node communication and degraded performance
  • +
+

Each time this happened, we had to manually rebalance shards just to restore stable latency, making operations unsustainable at scale.

+

Silver Linings

+

Despite the chaos, the system was live and delivering value:

+
    +
  • Real-time infrastructure was in production
  • +
  • Costs dropped by 60–70% compared to offline personalization
  • +
  • New experiments rolled out faster and more successfully
  • +
  • User engagement metrics improved
  • +
+

It wasn’t perfect. It was far from easy. But it worked—and that counted for a lot.

+

Round Two: Solving the Top 2 Bottlenecks

+

With the first-gen system stretched to its limits, we stepped back. Conversations with data scientists and backend engineers revealed three recurring pain points:

+
    +
  1. Coding feature retrieval logic for every new model was becoming unsustainable
  2. +
  3. ML scale was exploding—bringing rising infra costs with it
  4. +
  5. Real-time embedding search was the next big unlock
  6. +
+

We tackled them one by one—starting with the biggest pain point.

+

Problem 1: No-Code Feature Retrieval for Model Inference

+

We noticed a pattern: for personalized ranking, models needed features from:

+
    +
  • ✅ Product
  • +
  • ✅ User
  • +
  • ✅ User × Category
  • +
  • ✅ Region, cohort, sub-category, etc.
  • +
+

A key insight emerged: Entities that contribute features for a model always map back to the context entities.

+

MP Dag

+

With this, we designed Inferflow, a graph-driven feature retrieval and model orchestration system:

+
    +
  • 1️⃣ Inferflow takes a modelId and context IDs (e.g., userId, productIds)
  • +
  • 2️⃣ Loads a pre-defined feature retrieval graph from ZooKeeper
  • +
  • 3️⃣ Executes the graph to resolve entity relationships dynamically
  • +
  • 4️⃣ Outputs a 2D matrix of feature vectors
  • +
+

💡 The impact?

+
    +
  • 🚀 No more custom feature retrieval code—just graph updates in config
  • +
  • 🚀 Feature consistency across experiments
  • +
  • 🚀 Faster iteration cycles for ranking, fraud detection, and beyond
  • +
+

Here’s a visual example that shows how this graph plays out during execution. We further extended the graph to call multiple models as needed: +MP matrix +We built Inferflow in GoLang, using gRPC and Proto3 serialization for efficiency.

+

Problem 2: Scaling Without Breaking the Bank

+

With more ML use cases coming online, we needed to cut costs without compromising performance. We focused on:

+
    +
  • 🔹 Online Feature Store
  • +
  • 🔹 Interaction Store
  • +
+

Optimizing the Online Feature Store

+

Our costs were concentrated in:

+
    +
  • 📌 Database (Cassandra)
  • +
  • 📌 Cache (Redis)
  • +
  • 📌 Running Pods (Java services)
  • +
+

1️⃣ Replacing Cassandra with ScyllaDB +As we hit the operational limits of large Cassandra clusters, we transitioned to ScyllaDB, which offered a seamless drop-in replacement without major code changes. The switch brought significant benefits:

+
    +
  • Throughput: Matched or exceeded Cassandra's performance under identical workloads, even under high concurrency.
  • +
  • Latency: Achieved consistently lower P99 latencies due to ScyllaDB's shard-per-core architecture and better I/O utilization.
  • +
  • Cost Efficiency: Reduced infra footprint by ~70% through better CPU and memory efficiency, eliminating the need for over-provisioned nodes.
  • +
+

2️⃣ Finding the Right Cache +To reduce backend load and improve response times, we benchmarked multiple caching solutions—Memcached, KeyDB, and Dragonfly—under real production traffic patterns. Dragonfly stood out due to its robust architecture and operational simplicity:

+
    +
  • Data Skew Handling: Efficiently managed extreme key hotness and uneven access patterns without performance degradation.
  • +
  • Throughput: Delivered consistently high throughput, even with large object sizes and concurrent access.
  • +
  • Ease of Adoption: Acted as a drop-in Redis replacement with full protocol compatibility—no changes needed in application code or client libraries.
  • +
+

3️⃣ Moving to GoLang for Cost-Efficient Serving +Java services were memory-heavy—so we rewrote core services in GoLang. The results?

+

✅ Memory usage dropped by ~80% +✅ CPU utilization was significantly lower +✅ Faster, more efficient deployments

+

Optimizing the Interaction Store

+

We realized that we only need a user’s interaction data in Redis when they open the app. So, we implemented a tiered storage approach:

+
    +
  • 📌 Cold Tier (ScyllaDB)—Stores click, order, wishlist events
  • +
  • 📌 Hot Tier (Redis)—Loads a user’s past interactions only when they open the app
  • +
+

Smart Offloading: We introduced an inactivity tracker to detect when a user session ends. At that point, Redis data was flushed back to Scylla, reducing unnecessary writes.

+

InteractionStore

+

Results

+
    +
  • Online Feature Store hit 1M QPS for the first time during the 2023 Mega Blockbuster Sale—without breaking a sweat
  • +
  • Infra costs for Online Feature Store and Interaction Store dropped by ~60%
  • +
+

The Catch: Our ML Hosting Hit a Hard Limit

+

While planning for 2023 MBS, we ran into a critical scalability bottleneck:

+
    +
  • ❌ Insufficient compute availability in our region for ML instances
  • +
  • ❌ Couldn’t provision enough nodes to handle real-time inference at scale
  • +
+

This forced us to rethink where and how we hosted our models. The existing setup was great for prototyping—but it wasn’t built to handle the bursty, high-QPS demands of real-world production workloads.

+

Conclusion: From Firefighting to Future-Proofing

+

What started as an ambitious experiment turned into a real-time ML infrastructure that powered millions of requests per second. We battled scaling pains, rethought feature retrieval with Inferflow, and rebuilt our infra stack for efficiency—driving down costs while improving experimentation velocity. +But new challenges emerged. Our infrastructure could now handle scale, but our ML model hosting setup hit a hard limit. With compute availability bottlenecks threatening real-time inference, we faced a critical decision: how do we make model serving as scalable and cost-efficient as the rest of our stack? That’s the next piece of the puzzle—and the story of Part 3.

]]>
+ + Bhawani Singh + https://github.com/singh-bhawani + + + Jigar Dave + https://github.com/jigarpatel26 + + + Adarsha Das + https://github.com/a0d00kc + + + + + + +
<![CDATA[Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1)]]> https://meesho.github.io/BharatMLStack/blog/post-one 2022-11-15T00:00:00.000Z - BharatMLStack

+ BharatMLStack

The Genesis: How a Friday Night Roast Sparked Meesho’s ML Platform

It all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting—until one remark hit a little too close to home:

"Why are we still crunching data for Monthly Active Users (MAU) when the next day it’s all about Daily Active Users (DAU)?"

diff --git a/docs/blog/authors/index.html b/docs/blog/authors/index.html index af01797d..441c4c45 100644 --- a/docs/blog/authors/index.html +++ b/docs/blog/authors/index.html @@ -4,14 +4,14 @@ Authors | BharatMLStack - - - + + + -

Authors

+ \ No newline at end of file diff --git a/docs/blog/index.html b/docs/blog/index.html index b033836d..6bfb6e82 100644 --- a/docs/blog/index.html +++ b/docs/blog/index.html @@ -3,16 +3,359 @@ -Blog | BharatMLStack - - - +Blog | BharatMLStack + + + -

Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1)

· 11 min read
Adarsha Das
Senior Architect @ Meesho
Aditya Kumar
SDE-III @ Meesho
Bhawani Singh
SDE-IV @ Meesho
Jigar Dave
SDE-IV @ Meesho

BharatMLStack

+

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

· 5 min read
Jaya Kumar
Lead ML Engineer @ Meesho

BharatMLStack

+

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

+

Raw execution of Large Language Models is inherently expensive and memory-intensive. To achieve sub-second latency and high throughput, we implement a multi-layered optimization strategy that targets the entire inference stack—from memory management to kernel execution.

+

1. Advanced Memory Management: Paged & Prefix KV Caching

+

The most significant bottleneck in LLM inference is not always compute, but memory bandwidth—specifically managing the Key-Value (KV) cache.

+

Paged KV caching

+

Standard caching suffers from fragmentation. We use Paged KV caching, which operates similarly to an operating system's virtual memory: the KV cache is divided into non-contiguous blocks. This lets us serve larger batch sizes without running out of memory.

+

KV cache quantization

+

To further maximize available memory, we implement KV cache quantization (e.g., FP8). By compressing stored attention keys and values from 16-bit to 8-bit, we nearly double the effective context window capacity of the GPU, allowing longer conversations or larger batches without materially degrading quality.

+

Prefix caching (the "voice bot" optimizer)

+

For use cases like GenAI voice bots where the system prompt (e.g., "You are a helpful assistant...") is static across thousands of requests, we enable prefix caching.

+
    +
  • Impact: By reusing pre-computed KV states for common prefixes, we achieve a cache hit rate of ~90%. This reduces Time To First Token (TTFT) by skipping redundant computation of the system prompt.
  • +
+

2. Aggressive Quantization (INT4 AWQ & FP8)

+

Running models in their native 16-bit precision (BF16) restricts maximum batch size and throughput. We use quantization to shrink model weights without sacrificing accuracy.

+

INT4 AWQ (Activation-aware Weight Quantization)

+

For the Llama 3 family, we use AWQ to compress weights to 4 bits. This reduces model size by ~75%, allowing larger models to fit into L4 GPU memory and significantly improving token generation speed.

+

FP8 precision

+

For NVIDIA Hopper (H100) architectures, we are exploring FP8 quantization, leveraging native FP8 tensor cores to accelerate matrix multiplications while maintaining a higher dynamic range than integer quantization.

+
    +
  • Verification: We validate quantized models by comparing dot-product similarity of embeddings against the FP16 baseline, consistently achieving >99% similarity.
  • +
+

3. Kernel Fusion & Custom Plugins

+

To minimize overhead from launching thousands of small GPU operations, we fuse them into monolithic kernels using NVIDIA TensorRT plugins.

+
    +
  • Flash attention & FMHA: We enable Fused Multi-Head Attention (FMHA) combined with flash attention to reduce memory reads/writes.
  • +
  • GEMM plugins: We use specialized GEMM plugins to accelerate transformer linear layers.
  • +
  • Removing input padding: Instead of padding short sequences to match the longest, we remove input padding so the GPU processes only valid tokens.
  • +
+

4. Inflight (Continuous) Batching

+

Traditional static batching waits for all requests in a batch to finish before returning results—so one long response delays everyone else.

+

We implement inflight batching: as soon as one request completes, its slot is freed and filled by a new request from the queue. This keeps GPUs saturated and decouples latency of short queries from long ones.

+

5. Parallelism Strategies: Scaling Beyond One GPU

+

For large models (e.g., 70B+ parameters) that cannot fit into the VRAM of a single GPU, we use parallelism strategies.

+
    +
  • Tensor parallelism (TP): Split weight matrices across multiple GPUs (e.g., 4× L4 or 8× A100). Each GPU computes a shard and outputs are reduced at every layer.
  • +
  • Pipeline parallelism (PP): Split model layers across GPUs to pipeline compute (e.g., while one GPU computes later layers for Request A, another starts early layers for Request B).
  • +
+

6. Speculative Decoding

+

To reduce inter-token latency (ITL), we explore speculative decoding.

+
    +
  • Mechanism: A smaller, faster "draft" model speculatively generates a short token sequence (e.g., 5 tokens).
  • +
  • Verification: The larger target model verifies those tokens in one parallel forward pass. If correct, we effectively generate multiple tokens per large-model step; if not, we discard and regenerate. This is effective for predictable text, improving perceived generation speed.
  • +
+

Few Benchmarks

+

Below are a couple of representative use cases and performance numbers.

+

Search query rewriting

+
    +
  • LLM: Fine-tuned llama-3.2-1B
  • +
  • Input & output token length: ~10–20
  • +
  • Response type: Non-streaming
  • +
+
Inference runtimeHardwareMax requests/secMax p99 latency
TensorRT-LLM4 × L4 GPUs (multi-GPU)100095 ms
TensorRT-LLM1 × A100 40 GB GPU100069 ms
+

Voice bot query

+
    +
  • LLM: Llama-3.1-8B
  • +
  • Input token length: ~1900–2000
  • +
  • Output token length: ~200
  • +
  • Response type: Streaming
  • +
+
Inference runtimeConcurrencyp99 TTFT (ms)p99 ITL (ms)Token throughput (tokens/sec)Request throughput (req/sec)Hardware
TensorRT-LLM136.2722.7845.660.23L4
TensorRT-LLM249.8123.2189.370.45L4
TensorRT-LLM455.3336.62153.390.78L4
TensorRT-LLM866.539.11279.881.47L4
TensorRT-LLM16131.830.39547.82.77L4
TensorRT-LLM32277.2248.02925.74.78L4
TensorRT-LLM64498.5271.621,164.406.2L4
TensorRT-LLM128677.31120.371,445.187.69L4
TensorRT-LLM2561,926.31216.881,600.818.52L4
TensorRT-LLM121.179.24130.050.68A100
TensorRT-LLM225.789.21264.51.35A100
TensorRT-LLM428.5210.99437.692.27A100
TensorRT-LLM834.412.61760.493.96A100
TensorRT-LLM1668.0314.321,343.807.01A100
TensorRT-LLM32185.9616.822,287.3011.92A100
TensorRT-LLM64136.8721.173,625.2218.89A100
TensorRT-LLM128463.7834.154,456.5123.24A100
TensorRT-LLM256890.1259.185,188.2427.05A100
+

Conclusion

+

High-performance LLM inference is fundamentally a systems engineering problem: memory efficiency, kernel execution, batching strategy, and parallelism determine real-world latency and throughput. Techniques such as paged KV caching, aggressive quantization, kernel fusion, and inflight batching improve GPU utilization while reducing latency and memory pressure.

+

These optimizations enable the platform to deliver sub-second responses, sustain high concurrency, and efficiently serve both lightweight and long-context workloads. By continuously optimizing across the full inference stack, we keep LLM serving scalable, cost-efficient, and production-ready for real-time AI applications.

Cracking the Code: Scaling Model Inference & Real-Time Embedding Search

· 4 min read
Aditya Kumar
Lead Software Engineer @ Meesho
Jaya Kumar
Lead ML Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+ +

By mid-2023, we had transformed our ML stack—building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:

+
    +
  • 🔹 Scaling model inference without hitting infrastructure roadblocks
  • +
  • 🔹 Moving embedding search from batch to real-time for candidate generation
  • +
+

Here’s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system.

+

Breaking Free from the Scalability Ceiling

+

The Model Serving Bottleneck—A Wake-Up Call

+

July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue—scaling our model-serving infrastructure was taking 10–15 minutes. In real-time ML, that’s an eternity. +In one of our war rooms, we ran a quick experiment:

+
    +
  • 🚀 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine.
  • +
  • 🚀 Fired requests and compared the outputs with our existing cloud-hosted setup.
  • +
  • 🚀 The results matched—perfectly.
  • +
+

That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn't allocate enough compute resources in time. Luckily, they did—but the seed was planted. +Then in October, just two weeks before MBS, we got an alarming response from our infrastructure team: +"Node availability may be an issue." +With no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?

+
    +
  • ✅ p99 latency dropped from 90–100ms to 30–40ms
  • +
  • ✅ Triton handled significantly higher throughput on fewer resources
  • +
  • ✅ No model changes were needed
  • +
+

MBS ran without a hitch, proving that self-hosted inference was the way forward.

+

Scaling Triton on GKE

+

This left us with two choices:

+
    +
  • 1️⃣ Port models to a managed cloud inference service, investing time in learning a new deployment stack
  • +
  • 2️⃣ Scale our existing Triton setup on GKE, optimizing for cost and performance
  • +
+

We went with Option 2—and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations.

+

Fixing the Cold Start Problem

+

As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7–9 minutes to spin up.

+

After profiling, we found the culprits:

+
    +
  • Triton’s base image—a massive 5GB
  • +
  • Model binaries—often 1GB+
  • +
  • Startup delay—mostly due to downloading and initializing these assets
  • +
+

To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother.

+

Embedding Search: The Last Piece of the Puzzle

+

By mid-2023, most of our ML stack had gone real-time—except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system.

+

Choosing the Right Vector Database

+

We benchmarked three production-ready vector DBs across key parameters:

+
    +
  • Milvus
  • +
  • Qdrant
  • +
  • Weaviate
  • +
+

After extensive POCs, Qdrant stood out for its:

+
    +
  • ✅ Blazing-fast search latency on high-dimensional vectors
  • +
  • ✅ Efficient memory usage, crucial for in-memory workloads
  • +
  • ✅ Support for upserts and soft deletes, vital for Ads use cases
  • +
  • ✅ gRPC + REST APIs, making integration seamless
  • +
  • ✅ Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)
  • +
+

At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search—a perfect fit for our needs.

+

Embedding Freshness & Real-Time Updates

+

To ensure embeddings stayed up to date, we built a dual ingestion pipeline:

+
    +
  • 📌 Daily Refresh: A bulk pipeline updated embeddings overnight
  • +
  • 📌 Real-Time Updates: Ads events triggered immediate upserts/deletes
  • +
+

This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.

+

Skye

+

Final Takeaways: Scaling Smartly for Real-Time ML

+
    +
  • 🚀 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services
  • +
  • 🚀 Building a custom Triton image reduced cold starts, improving responsiveness
  • +
  • 🚀 Qdrant-based embedding search enabled real-time personalization at scale
  • +
  • 🚀 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations
  • +
+

By early 2024, Meesho’s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead.

Cracking the Code: Scaling Model Inference & Real-Time Embedding Search

· 4 min read
Aditya Kumar
Lead Software Engineer @ Meesho
Jaya Kumar
Lead ML Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+ +

By mid-2023, we had transformed our ML stack—building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:

+
    +
  • 🔹 Scaling model inference without hitting infrastructure roadblocks
  • +
  • 🔹 Moving embedding search from batch to real-time for candidate generation
  • +
+

Here’s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system.

+

Breaking Free from the Scalability Ceiling

+

The Model Serving Bottleneck—A Wake-Up Call

+

July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue—scaling our model-serving infrastructure was taking 10–15 minutes. In real-time ML, that’s an eternity. +In one of our war rooms, we ran a quick experiment:

+
    +
  • 🚀 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine.
  • +
  • 🚀 Fired requests and compared the outputs with our existing cloud-hosted setup.
  • +
  • 🚀 The results matched—perfectly.
  • +
+

That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn't allocate enough compute resources in time. Luckily, they did—but the seed was planted. +Then in October, just two weeks before MBS, we got an alarming response from our infrastructure team: +"Node availability may be an issue." +With no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?

+
    +
  • ✅ p99 latency dropped from 90–100ms to 30–40ms
  • +
  • ✅ Triton handled significantly higher throughput on fewer resources
  • +
  • ✅ No model changes were needed
  • +
+

MBS ran without a hitch, proving that self-hosted inference was the way forward.

+

Scaling Triton on GKE

+

This left us with two choices:

+
    +
  • 1️⃣ Port models to a managed cloud inference service, investing time in learning a new deployment stack
  • +
  • 2️⃣ Scale our existing Triton setup on GKE, optimizing for cost and performance
  • +
+

We went with Option 2—and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations.

+

Fixing the Cold Start Problem

+

As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7–9 minutes to spin up.

+

After profiling, we found the culprits:

+
    +
  • Triton’s base image—a massive 5GB
  • +
  • Model binaries—often 1GB+
  • +
  • Startup delay—mostly due to downloading and initializing these assets
  • +
+

To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother.

+

Embedding Search: The Last Piece of the Puzzle

+

By mid-2023, most of our ML stack had gone real-time—except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system.

+

Choosing the Right Vector Database

+

We benchmarked three production-ready vector DBs across key parameters:

+
    +
  • Milvus
  • +
  • Qdrant
  • +
  • Weaviate
  • +
+

After extensive POCs, Qdrant stood out for its:

+
    +
  • ✅ Blazing-fast search latency on high-dimensional vectors
  • +
  • ✅ Efficient memory usage, crucial for in-memory workloads
  • +
  • ✅ Support for upserts and soft deletes, vital for Ads use cases
  • +
  • ✅ gRPC + REST APIs, making integration seamless
  • +
  • ✅ Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)
  • +
+

At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search—a perfect fit for our needs.

+

Embedding Freshness & Real-Time Updates

+

To ensure embeddings stayed up to date, we built a dual ingestion pipeline:

+
    +
  • 📌 Daily Refresh: A bulk pipeline updated embeddings overnight
  • +
  • 📌 Real-Time Updates: Ads events triggered immediate upserts/deletes
  • +
+

This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.

+

Skye

+

Final Takeaways: Scaling Smartly for Real-Time ML

+
    +
  • 🚀 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services
  • +
  • 🚀 Building a custom Triton image reduced cold starts, improving responsiveness
  • +
  • 🚀 Qdrant-based embedding search enabled real-time personalization at scale
  • +
  • 🚀 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations
  • +
+

By early 2024, Meesho’s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead.

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

· 7 min read
Bhawani Singh
Architect @ Meesho
Jigar Dave
Lead Software Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

+

By late 2022, we had built something we were truly proud of—a real-time ML serving system with a DAG-based executor, a feature store, and an interaction store powering key ranking and personalization models. It was a major milestone, the culmination of months of effort from data scientists, ML engineers, and backend teams. Our system was live, and we were ready to push the boundaries of experimentation. +And it worked. Mostly. +But soon, cracks appeared. Every new model needed custom feature retrieval logic, DAGs became dense and unmanageable, and scaling turned into a constant firefight. Costs surged, and infra bottlenecks slowed experimentation. Our system worked, but it wasn’t built for scale. +This is the story of how we tackled these challenges—building Inferflow for seamless feature retrieval, optimizing real-time infra, and cutting costs while scaling to millions of QPS.

+

The Cost of Success

+

Every new Ranker model required its own feature set, often pulling from different entities. Each addition meant:

+
    +
  • Adding new DAG nodes in IOP
  • +
  • Writing custom logic to fetch features from multiple sources (e.g., user, product, user × category)
  • +
  • Inferring intermediate features (e.g., extracting category from a product to fetch user × category data)
  • +
  • Optimizing I/O and dealing with the inevitable bugs
  • +
+

What began as clean DAGs soon turned into a tangled web of cross-dependent graphs. Every experimentation cycle meant new nodes, new dependencies, and slower iterations.

+

Scaling Pains (and Cassandra’s Limits)

+

At some point, we were hitting:

+
    +
  • 250–300K reads/sec
  • +
  • 1M writes/sec (during lean hours)
  • +
+

All of this ran on Cassandra. While its distributed architecture had been proven in production, operating large-scale clusters came with considerable infrastructure overhead. Our proof-of-concept (POC) demonstrated throughput of around 100K ops/sec, but as we scaled further, the challenges grew. Ensuring node health, optimizing compaction, and maintaining storage balance became increasingly demanding. We also observed latency spikes under heavy load, alongside a sharp increase in total cost of ownership.

+

Interaction Store Woes

+

Our interaction store was another ticking time bomb:

+
    +
  • 🚨 Clusters kept growing in size and cost
  • +
  • 🚨 Latency spikes became increasingly frequent
  • +
  • 🚨 The DMC proxy occasionally lost locality of nodes against shards, causing cross-node communication and degraded performance
  • +
+

Each time this happened, we had to manually rebalance shards just to restore stable latency, making operations unsustainable at scale.

+

Silver Linings

+

Despite the chaos, the system was live and delivering value:

+
    +
  • Real-time infrastructure was in production
  • +
  • Costs dropped by 60–70% compared to offline personalization
  • +
  • New experiments rolled out faster and more successfully
  • +
  • User engagement metrics improved
  • +
+

It wasn’t perfect. It was far from easy. But it worked—and that counted for a lot.

+

Round Two: Solving the Top 2 Bottlenecks

+

With the first-gen system stretched to its limits, we stepped back. Conversations with data scientists and backend engineers revealed three recurring pain points:

+
    +
  1. Coding feature retrieval logic for every new model was becoming unsustainable
  2. +
  3. ML scale was exploding—bringing rising infra costs with it
  4. +
  5. Real-time embedding search was the next big unlock
  6. +
+

We tackled them one by one—starting with the biggest pain point.

+

Problem 1: No-Code Feature Retrieval for Model Inference

+

We noticed a pattern: for personalized ranking, models needed features from:

+
    +
  • ✅ Product
  • +
  • ✅ User
  • +
  • ✅ User × Category
  • +
  • ✅ Region, cohort, sub-category, etc.
  • +
+

A key insight emerged: Entities that contribute features for a model always map back to the context entities.

+

MP Dag

+

With this, we designed Inferflow, a graph-driven feature retrieval and model orchestration system:

+
    +
  • 1️⃣ Inferflow takes a modelId and context IDs (e.g., userId, productIds)
  • +
  • 2️⃣ Loads a pre-defined feature retrieval graph from ZooKeeper
  • +
  • 3️⃣ Executes the graph to resolve entity relationships dynamically
  • +
  • 4️⃣ Outputs a 2D matrix of feature vectors
  • +
+

💡 The impact?

+
    +
  • 🚀 No more custom feature retrieval code—just graph updates in config
  • +
  • 🚀 Feature consistency across experiments
  • +
  • 🚀 Faster iteration cycles for ranking, fraud detection, and beyond
  • +
+

Here’s a visual example that shows how this graph plays out during execution. We further extended the graph to call multiple models as needed: +MP matrix +We built Inferflow in GoLang, using gRPC and Proto3 serialization for efficiency.

+

Problem 2: Scaling Without Breaking the Bank

+

With more ML use cases coming online, we needed to cut costs without compromising performance. We focused on:

+
    +
  • 🔹 Online Feature Store
  • +
  • 🔹 Interaction Store
  • +
+

Optimizing the Online Feature Store

+

Our costs were concentrated in:

+
    +
  • 📌 Database (Cassandra)
  • +
  • 📌 Cache (Redis)
  • +
  • 📌 Running Pods (Java services)
  • +
+

1️⃣ Replacing Cassandra with ScyllaDB +As we hit the operational limits of large Cassandra clusters, we transitioned to ScyllaDB, which offered a seamless drop-in replacement without major code changes. The switch brought significant benefits:

+
    +
  • Throughput: Matched or exceeded Cassandra's performance under identical workloads, even under high concurrency.
  • +
  • Latency: Achieved consistently lower P99 latencies due to ScyllaDB's shard-per-core architecture and better I/O utilization.
  • +
  • Cost Efficiency: Reduced infra footprint by ~70% through better CPU and memory efficiency, eliminating the need for over-provisioned nodes.
  • +
+

2️⃣ Finding the Right Cache +To reduce backend load and improve response times, we benchmarked multiple caching solutions—Memcached, KeyDB, and Dragonfly—under real production traffic patterns. Dragonfly stood out due to its robust architecture and operational simplicity:

+
    +
  • Data Skew Handling: Efficiently managed extreme key hotness and uneven access patterns without performance degradation.
  • +
  • Throughput: Delivered consistently high throughput, even with large object sizes and concurrent access.
  • +
  • Ease of Adoption: Acted as a drop-in Redis replacement with full protocol compatibility—no changes needed in application code or client libraries.
  • +
+

3️⃣ Moving to GoLang for Cost-Efficient Serving +Java services were memory-heavy—so we rewrote core services in GoLang. The results?

+

✅ Memory usage dropped by ~80% +✅ CPU utilization was significantly lower +✅ Faster, more efficient deployments

+

Optimizing the Interaction Store

+

We realized that we only need a user’s interaction data in Redis when they open the app. So, we implemented a tiered storage approach:

+
    +
  • 📌 Cold Tier (ScyllaDB)—Stores click, order, wishlist events
  • +
  • 📌 Hot Tier (Redis)—Loads a user’s past interactions only when they open the app
  • +
+

Smart Offloading: We introduced an inactivity tracker to detect when a user session ends. At that point, Redis data was flushed back to Scylla, reducing unnecessary writes.

+

InteractionStore

+

Results

+
    +
  • Online Feature Store hit 1M QPS for the first time during the 2023 Mega Blockbuster Sale—without breaking a sweat
  • +
  • Infra costs for Online Feature Store and Interaction Store dropped by ~60%
  • +
+

The Catch: Our ML Hosting Hit a Hard Limit

+

While planning for 2023 MBS, we ran into a critical scalability bottleneck:

+
    +
  • ❌ Insufficient compute availability in our region for ML instances
  • +
  • ❌ Couldn’t provision enough nodes to handle real-time inference at scale
  • +
+

This forced us to rethink where and how we hosted our models. The existing setup was great for prototyping—but it wasn’t built to handle the bursty, high-QPS demands of real-world production workloads.

+

Conclusion: From Firefighting to Future-Proofing

+

What started as an ambitious experiment turned into a real-time ML infrastructure that powered millions of requests per second. We battled scaling pains, rethought feature retrieval with Inferflow, and rebuilt our infra stack for efficiency—driving down costs while improving experimentation velocity. +But new challenges emerged. Our infrastructure could now handle scale, but our ML model hosting setup hit a hard limit. With compute availability bottlenecks threatening real-time inference, we faced a critical decision: how do we make model serving as scalable and cost-efficient as the rest of our stack? That’s the next piece of the puzzle—and the story of Part 3.

Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1)

· 11 min read
Adarsha Das
Senior Architect @ Meesho
Aditya Kumar
Lead Software Engineer @ Meesho
Bhawani Singh
Architect @ Meesho
Jigar Dave
Lead Software Engineer @ Meesho

BharatMLStack

The Genesis: How a Friday Night Roast Sparked Meesho’s ML Platform

It all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting—until one remark hit a little too close to home:

"Why are we still crunching data for Monthly Active Users (MAU) when the next day it’s all about Daily Active Users (DAU)?"

@@ -204,6 +547,6 @@

+

This foundational work laid the path for a reliable and scalable real-time feature serving layer.

\ No newline at end of file diff --git a/docs/blog/post-five/index.html b/docs/blog/post-five/index.html new file mode 100644 index 00000000..01dc8558 --- /dev/null +++ b/docs/blog/post-five/index.html @@ -0,0 +1,81 @@ + + + + + +LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale | BharatMLStack + + + + + + + + +

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

· 5 min read
Jaya Kumar
Lead ML Engineer @ Meesho

BharatMLStack

+

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

+

Raw execution of Large Language Models is inherently expensive and memory-intensive. To achieve sub-second latency and high throughput, we implement a multi-layered optimization strategy that targets the entire inference stack—from memory management to kernel execution.

+

1. Advanced Memory Management: Paged & Prefix KV Caching

+

The most significant bottleneck in LLM inference is not always compute, but memory bandwidth—specifically managing the Key-Value (KV) cache.

+

Paged KV caching

+

Standard caching suffers from fragmentation. We use Paged KV caching, which operates similarly to an operating system's virtual memory: the KV cache is divided into non-contiguous blocks. This lets us serve larger batch sizes without running out of memory.

+

KV cache quantization

+

To further maximize available memory, we implement KV cache quantization (e.g., FP8). By compressing stored attention keys and values from 16-bit to 8-bit, we nearly double the effective context window capacity of the GPU, allowing longer conversations or larger batches without materially degrading quality.

+

Prefix caching (the "voice bot" optimizer)

+

For use cases like GenAI voice bots where the system prompt (e.g., "You are a helpful assistant...") is static across thousands of requests, we enable prefix caching.

+
    +
  • Impact: By reusing pre-computed KV states for common prefixes, we achieve a cache hit rate of ~90%. This reduces Time To First Token (TTFT) by skipping redundant computation of the system prompt.
  • +
+

2. Aggressive Quantization (INT4 AWQ & FP8)

+

Running models in their native 16-bit precision (BF16) restricts maximum batch size and throughput. We use quantization to shrink model weights without sacrificing accuracy.

+

INT4 AWQ (Activation-aware Weight Quantization)

+

For the Llama 3 family, we use AWQ to compress weights to 4 bits. This reduces model size by ~75%, allowing larger models to fit into L4 GPU memory and significantly improving token generation speed.

+

FP8 precision

+

For NVIDIA Hopper (H100) architectures, we are exploring FP8 quantization, leveraging native FP8 tensor cores to accelerate matrix multiplications while maintaining a higher dynamic range than integer quantization.

+
    +
  • Verification: We validate quantized models by comparing dot-product similarity of embeddings against the FP16 baseline, consistently achieving >99% similarity.
  • +
+

3. Kernel Fusion & Custom Plugins

+

To minimize overhead from launching thousands of small GPU operations, we fuse them into monolithic kernels using NVIDIA TensorRT plugins.

+
    +
  • Flash attention & FMHA: We enable Fused Multi-Head Attention (FMHA) combined with flash attention to reduce memory reads/writes.
  • +
  • GEMM plugins: We use specialized GEMM plugins to accelerate transformer linear layers.
  • +
  • Removing input padding: Instead of padding short sequences to match the longest, we remove input padding so the GPU processes only valid tokens.
  • +
+

4. Inflight (Continuous) Batching

+

Traditional static batching waits for all requests in a batch to finish before returning results—so one long response delays everyone else.

+

We implement inflight batching: as soon as one request completes, its slot is freed and filled by a new request from the queue. This keeps GPUs saturated and decouples latency of short queries from long ones.

+

5. Parallelism Strategies: Scaling Beyond One GPU

+

For large models (e.g., 70B+ parameters) that cannot fit into the VRAM of a single GPU, we use parallelism strategies.

+
    +
  • Tensor parallelism (TP): Split weight matrices across multiple GPUs (e.g., 4× L4 or 8× A100). Each GPU computes a shard and outputs are reduced at every layer.
  • +
  • Pipeline parallelism (PP): Split model layers across GPUs to pipeline compute (e.g., while one GPU computes later layers for Request A, another starts early layers for Request B).
  • +
+

6. Speculative Decoding

+

To reduce inter-token latency (ITL), we explore speculative decoding.

+
    +
  • Mechanism: A smaller, faster "draft" model speculatively generates a short token sequence (e.g., 5 tokens).
  • +
  • Verification: The larger target model verifies those tokens in one parallel forward pass. If correct, we effectively generate multiple tokens per large-model step; if not, we discard and regenerate. This is effective for predictable text, improving perceived generation speed.
  • +
+

Few Benchmarks

+

Below are a couple of representative use cases and performance numbers.

+

Search query rewriting

+
    +
  • LLM: Fine-tuned llama-3.2-1B
  • +
  • Input & output token length: ~10–20
  • +
  • Response type: Non-streaming
  • +
+
Inference runtimeHardwareMax requests/secMax p99 latency
TensorRT-LLM4 × L4 GPUs (multi-GPU)100095 ms
TensorRT-LLM1 × A100 40 GB GPU100069 ms
+

Voice bot query

+
    +
  • LLM: Llama-3.1-8B
  • +
  • Input token length: ~1900–2000
  • +
  • Output token length: ~200
  • +
  • Response type: Streaming
  • +
+
Inference runtimeConcurrencyp99 TTFT (ms)p99 ITL (ms)Token throughput (tokens/sec)Request throughput (req/sec)Hardware
TensorRT-LLM136.2722.7845.660.23L4
TensorRT-LLM249.8123.2189.370.45L4
TensorRT-LLM455.3336.62153.390.78L4
TensorRT-LLM866.539.11279.881.47L4
TensorRT-LLM16131.830.39547.82.77L4
TensorRT-LLM32277.2248.02925.74.78L4
TensorRT-LLM64498.5271.621,164.406.2L4
TensorRT-LLM128677.31120.371,445.187.69L4
TensorRT-LLM2561,926.31216.881,600.818.52L4
TensorRT-LLM121.179.24130.050.68A100
TensorRT-LLM225.789.21264.51.35A100
TensorRT-LLM428.5210.99437.692.27A100
TensorRT-LLM834.412.61760.493.96A100
TensorRT-LLM1668.0314.321,343.807.01A100
TensorRT-LLM32185.9616.822,287.3011.92A100
TensorRT-LLM64136.8721.173,625.2218.89A100
TensorRT-LLM128463.7834.154,456.5123.24A100
TensorRT-LLM256890.1259.185,188.2427.05A100
+

Conclusion

+

High-performance LLM inference is fundamentally a systems engineering problem: memory efficiency, kernel execution, batching strategy, and parallelism determine real-world latency and throughput. Techniques such as paged KV caching, aggressive quantization, kernel fusion, and inflight batching improve GPU utilization while reducing latency and memory pressure.

+

These optimizations enable the platform to deliver sub-second responses, sustain high concurrency, and efficiently serve both lightweight and long-context workloads. By continuously optimizing across the full inference stack, we keep LLM serving scalable, cost-efficient, and production-ready for real-time AI applications.

+ + \ No newline at end of file diff --git a/docs/blog/post-one/index.html b/docs/blog/post-one/index.html index c202721c..2f484bd6 100644 --- a/docs/blog/post-one/index.html +++ b/docs/blog/post-one/index.html @@ -3,16 +3,16 @@ -Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1) | BharatMLStack - - - +Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1) | BharatMLStack + + + -

Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1)

· 11 min read
Adarsha Das
Senior Architect @ Meesho
Aditya Kumar
SDE-III @ Meesho
Bhawani Singh
SDE-IV @ Meesho
Jigar Dave
SDE-IV @ Meesho

BharatMLStack

+

Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1)

· 11 min read
Adarsha Das
Senior Architect @ Meesho
Aditya Kumar
Lead Software Engineer @ Meesho
Bhawani Singh
Architect @ Meesho
Jigar Dave
Lead Software Engineer @ Meesho

BharatMLStack

The Genesis: How a Friday Night Roast Sparked Meesho’s ML Platform

It all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting—until one remark hit a little too close to home:

"Why are we still crunching data for Monthly Active Users (MAU) when the next day it’s all about Daily Active Users (DAU)?"

@@ -204,6 +204,6 @@

+

This foundational work laid the path for a reliable and scalable real-time feature serving layer.

\ No newline at end of file diff --git a/docs/blog/post-three/index.html b/docs/blog/post-three/index.html new file mode 100644 index 00000000..a160d2ad --- /dev/null +++ b/docs/blog/post-three/index.html @@ -0,0 +1,206 @@ + + + + + +Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving | BharatMLStack + + + + + + + + +

Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving

· 14 min read
Jaya Kumar
Lead ML Engineer @ Meesho

BharatMLStack

+

Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving

+

Serving large language models in production introduces new challenges across infrastructure, performance optimization, and operational lifecycle management. The LLM Inference Platform addresses these challenges by providing a unified system for deploying and managing open-source and fine-tuned LLMs at scale.

+

The platform implements a complete LLMOps lifecycle — from model registration and automated compilation to deployment, runtime optimization, and monitoring. Designed as a self-service environment, users can onboard models directly from open repositories such as Hugging Face or upload custom fine-tuned models, and deploy them using a single-click workflow with no manual infrastructure or configuration steps required.

+

In addition to fully automated deployment, the platform allows users to select and apply custom inference optimization techniques — such as quantization strategies, batching configurations, and runtime-specific performance enhancements — enabling teams to balance latency, throughput, and cost based on their use case. The goal is to reduce operational friction while enabling high-performance, production-grade LLM inference.

+

Why LLM Inference Is not just bigger ML model serving

+

Large language model (LLM) inference introduces a fundamentally different set of challenges compared to traditional machine learning inference. While classical ML models typically perform a single forward pass to produce a fixed prediction, LLMs operate as autoregressive systems, generating outputs token by token based on previously generated context. This difference dramatically changes how inference systems must be designed, optimized, and scaled.

+

Autoregressive Generation and Sequential Computation:

+

Unlike traditional models such as classifiers or recommenders — where inference cost is relatively constant — LLMs generate responses incrementally. Each new token depends on all previously generated tokens, making inference inherently sequential and dynamic. This means latency and compute requirements vary significantly depending on prompt length and output size, introducing complexity in scheduling and resource allocation. +Because tokens cannot be generated fully in parallel during decoding, GPUs may become underutilized without specialized batching and scheduling strategies. This has led to the development of dedicated LLM inference engines optimized for token-level execution.

+

Prefill and Decode Phases:

+

LLM inference typically consists of two distinct stages:

+
    +
  • Prefill phase — the model processes the input prompt and builds internal representations. This stage is compute-heavy and highly parallelizable.
  • +
  • Decode phase — the model generates tokens sequentially, predicting one token at a time using previously generated context.
  • +
+

The decode stage often becomes memory-bound rather than compute-bound, which creates new performance bottlenecks compared to traditional ML workloads.

+

Context Management and KV Caching:

+

Another fundamental difference lies in how LLMs maintain context. Transformer-based models rely on attention mechanisms that require access to past token representations. To avoid recomputing these representations repeatedly, inference engines use key-value (KV) caching, which stores intermediate activations from previous tokens. +KV caching significantly improves performance by eliminating redundant computation, but it introduces new challenges:

+
    +
  • Memory consumption grows with sequence length and batch size
  • +
  • GPU memory becomes a critical bottleneck
  • +
  • Efficient memory management becomes essential for scaling concurrent requests
  • +
+

This tradeoff between compute efficiency and memory usage is unique to LLM inference workloads.

+

Dynamic and Irregular Workloads:

+

Traditional ML inference typically operates on fixed-size inputs with predictable latency. In contrast, LLM requests vary widely in prompt length, output length, and runtime behavior. As a result:

+
    +
  • Batch sizes must be dynamic rather than static
  • +
  • Requests may enter and leave batches asynchronously
  • +
  • Scheduling systems must continuously rebalance workloads to maximize GPU utilization
  • +
+

These characteristics require specialized serving architectures that differ significantly from standard ML serving pipelines.

+

Streaming and User Experience Constraints:

+

Another distinguishing factor is the expectation of real-time streaming responses. Instead of returning a single output, LLM systems often stream tokens to users as they are generated. +Because of these differences — sequential generation, growing memory requirements, dynamic workloads, and streaming constraints — LLM inference cannot be treated as a simple extension of existing ML serving systems. Production platforms must incorporate specialized runtime engines, advanced optimization techniques, and observability tailored specifically to LLM workloads.

+

LLMOps: High-Level Architecture

+

LLM Architecture

+

The LLM Inference Framework is designed as a fully automated, end-to-end system for deploying and operating open-source and fine-tuned large language models at scale. The architecture abstracts the complexity of model optimization, hardware selection, deployment, and runtime management into a unified workflow that enables users to move from raw model weights to production-ready inference endpoints with minimal manual intervention.

+

Our LLM Inference Framework is architected not just as a serving engine, but as a complete lifecycle management system. As illustrated in the high-level design below, the platform automates the journey of a model through seven distinct stages, ensuring reproducibility, performance, and scalability.

+
    +
  1. +

    Onboarding & Registration (The Source of Truth)

    +

    The lifecycle begins with the Data Scientist or engineer.

    +
      +
    • Model Ingestion: Users onboard models—whether open-source (Hugging Face, NeMo) or internally fine-tuned—via the Truffle Box SDK/UI.
    • +
    • LLM + Prompt Registry: Unlike traditional systems that only track model weights, our registry is a unified control plane. It stores both the Model Artifacts and the Prompt Templates. This allows Data Scientists to register and version-control prompts (e.g., "customer_support_v2") independently of the application code.
    • +
    +
  2. +
  3. +

    The "Black Box" Build Engine

    +

    Once a model is registered, the Automated LLM Compiler + Quantizer Module kicks off a background job on ephemeral GPU resources.

    +
      +
    • Transformation: The raw model is converted into a TRT-LLM Checkpoint.
    • +
    • Quantization: The system automatically applies quantization algorithms (like INT4 AWQ or FP8) to reduce memory footprint.
    • +
    • Engine Building: Finally, it compiles a highly optimized TRT Engine specifically tuned for the target hardware.
    • +
    +
  4. +
  5. +

    Intelligent Profiling & Validation

    +

    Before deployment, the new engine passes through the Hardware & Inference Runtime Profiler.

    +
      +
    • Benchmarking: This module empirically tests the engine against various hardware configurations (L4 vs. A100) and runtimes (TRT-LLM vs. vLLM).
    • +
    • Optimization: It recommends the optimal configuration that meets latency SLAs (Time-To-First-Token) while minimizing cost.
    • +
    +
  6. +
  7. +

    Smart Artifact Generation & Distribution

    +

    To solve the Kubernetes "Cold Start" problem, the LLM Serving Artifacts Generation module packages the model using a bifurcated strategy:

    +
      +
    • Standard Models: Artifacts are uploaded to Cloud Storage (GCS) and downloaded by pods at startup.
    • +
    • Very Large Models: For massive models (>8GB) where network downloads are too slow, the system pre-caches the model onto Secondary Boot Disks. These disks are attached directly to new GPU nodes during autoscaling, eliminating download wait times.
    • +
    +
  8. +
  9. +

    Image Streaming & Deployment

    +

    Simultaneously, the inference runtime container images are pulled from the Artifact Registry.

    +
      +
    • Image Streaming: We utilize container image streaming to allow pods to start initializing while the massive Triton/Dynamo container layers are still downloading, further shaving seconds off the startup time. link
    • +
    +
  10. +
  11. +

    The Inference Runtime (Kubernetes)

    +

    The workload lands on Kubernetes with Autoscaling.

    +
      +
    • Dynamic Backends: Depending on the profile generated in Stage 3, the pod initializes either TensorRT-LLM (for throughput) or vLLM (for flexibility), or spins up a Dynamo worker for distributed inference.
    • +
    • Data Loading: The pod either downloads the model from Cloud Storage or mounts the pre-warmed Secondary Boot Disk ("Pull from Disk").
    • +
    +
  12. +
  13. +

    Client Interaction & Observability

    +

    Finally, the LLM Inference Client executes the request.

    +
      +
    • Prompt Injection: The client pulls the specific prompt template ID from the Registry, ensuring the exact versioned instructions are used.
    • +
    • Streaming Response: The request is sent via gRPC, and tokens are streamed back to the user in real-time.
    • +
    +
  14. +
  15. +

    Observability: Monitoring the Pulse of GenAI

    +

    In traditional microservices, success is measured by CPU utilization and request latency (p99). For Large Language Models, these metrics are insufficient. A user doesn't care if the GPU is at 80% utilization; they care about how fast the first word appears and how smoothly the rest of the sentence follows.

    +

    To capture the true user experience, our platform instrumentation focuses on three critical LLM-specific metrics:

    +
      +
    1. +

      Time to First Token (TTFT)

      +
        +
      • Definition: TTFT measures the time elapsed from the moment a request is received until the very first token is generated and streamed back to the user.
      • +
      • Why it matters: This represents the "Prefill Phase" latency—the time the model takes to process the input prompt and load weights. A high TTFT makes the application feel unresponsive or "hung."
      • +
      • Optimization: We closely monitor TTFT to ensure our Prefix Caching is effective (aiming for high cache hitrates), which drastically lowers this metric by skipping redundant prompt processing.
      • +
      +
    2. +
    3. +

      Inter-Token Latency (ITL)

      +
        +
      • Definition: ITL measures the average time interval between the generation of consecutive tokens during the "Decode Phase".
      • +
      • Why it matters: This defines the "perceived speed" of reading. Even if the first token is fast (low TTFT), high ITL makes the text generation look "jerky" or slow to the user.
      • +
      • Benchmarks: In our testing with Llama 3.1, we track p99 ITL to ensure it stays below human reading speeds to maintain a natural conversational flow.
      • +
      +
    4. +
    5. +

      Token Throughput vs. Request Throughput

      +
        +
      • We distinguish between two types of throughput to balance system efficiency with user load:
      • +
      • Token Throughput (tokens/sec): The total number of tokens generated across all concurrent requests. This measures the raw compute efficiency of the GPU and the effectiveness of batching.
      • +
      • Request Throughput (req/sec): The number of distinct user queries served per second. We use this to determine autoscaling thresholds, ensuring we scale out before the queue depth impacts ITL.
      • +
      +
    6. +
    7. +

      The Monitoring Stack

      +
        +
      • Real-time Dashboards: We utilize Grafana to visualize these streaming metrics in real-time, allowing on-call engineers to spot "slow generation" incidents that generic "500 error" alerts would miss.
      • +
      • Request Tracing: Since Triton Inference Server does not log request payloads by default, we integrate a Helix Client to asynchronously publish request logs to Log Tables. This allows us to trace a specific "slow" request back to its prompt to understand if a complex input caused the latency spike.
      • +
      +
    8. +
    +
  16. +
+

Supported Inference backends (TensorRT LLM, Dynamo & vLLM)

+

Tailored for the Use Case: We do not believe in a "one-size-fits-all" approach to inference. Different use cases—whether a real-time voice bot requiring ultra-lowsub-second latency or a massive reasoning task requiring huge context windows—demand different runtime characteristics. Our platform is designed to be runtime-agnostic, allowing us to automatically select and tailor the best engine based on the specific requirements of the application:

+
    +
  1. +

    TensorRT-LLM: The High-Performance Standard

    +

    Suitable for: High-throughput production workloads where latency is critical (e.g., customer support chat, real-time voice bots).

    +

    TensorRT-LLM serves as our default backend for these scenarios. Our internal benchmarks on Llama 3.1 and 3.2 models demonstrated that a tuned TensorRT-LLM engine significantly outperforms standard runtimes, especially when utilizing INT4 AWQ and FP8 quantization .

    +

    Key optimizations we tailor for these high-load cases include:

    +
      +
    • Optimized execution via TensorRT engine compilation
    • +
    • Quantization-aware execution for reduced memory usage and improved throughput
    • +
    • Inflight Batching: Allowing requests to be processed continuously without waiting for the entire batch to finish, drastically improving GPU utilization .
    • +
    • Custom Plugins: Enabling specific NVIDIA plugins like the GEMM plugin and GPT Attention plugin to accelerate matrix multiplications and attention mechanisms .
    • +
    +
  2. +
  3. +

    Dynamo: Distributed Inference for Reasoning Models

    +

    Suitable for: Very large "reasoning" models (70B+) or scenarios requiring massive context windows where a single GPU's memory is insufficient.

    +

    For these memory-bound tasks, we utilize Dynamo, a low-latency distributed inference framework . Unlike monolithic servers, Dynamo disaggregates the inference process to scale resources horizontally:

    +
      +
    • KV Aware Routing: A specialized router directs requests to workers that already hold the relevant Key-Value (KV) cache, minimizing redundant computation .
    • +
    • Prefill vs. Decode Split: The workload is divided into Prefill Workers (processing the prompt) and Decode Workers (generating tokens), allowing us to scale the compute-heavy "reading" phase independently from the memory-heavy "writing" phase .
    • +
    • Distributed execution across multiple GPU resources
    • +
    +
  4. +
  5. +

    vLLM: The Flexible Baseline

    +

    Suitable for: Rapid prototyping, testing new model architectures, or low-traffic internal tools where ease of deployment outweighs raw throughput.

    +

    While TensorRT-LLM is optimized for maximum speed, vLLM provides a robust and flexible baseline .

    +
      +
    • High throughput through dynamic batching and efficient memory utilization
    • +
    • Paged KV cache management for handling long contexts and concurrent requests
    • +
    • Strong support for open-source model ecosystems
    • +
    • Rapid Adoption: It allows us to onboard new model architectures immediately without waiting for a custom TensorRT build.
    • +
    • Benchmarking Insight: In our internal tests, vLLM provided a strong baseline but often lacked the specific max-token optimizations present in our custom TRT engines . We use it strategically for initial testing before committing to a full TensorRT optimization pipeline.
    • +
    +
  6. +
+

Conclusion

+

Large language model inference introduces a fundamentally new class of infrastructure challenges—where performance is governed not just by raw compute, but by memory efficiency, intelligent scheduling, runtime specialization, and lifecycle automation. Unlike traditional ML serving, LLM inference requires systems that understand token-level execution, manage rapidly growing context state, and continuously balance latency, throughput, and cost under highly dynamic workloads.

+

The LLM Inference Framework addresses these challenges by transforming inference into a fully automated, reproducible lifecycle—from model onboarding and compilation to deployment, optimization, and observability. By integrating automated quantization and engine compilation, intelligent runtime selection, cold-start mitigation strategies, and LLM-specific observability metrics such as Time-to-First-Token and Inter-Token Latency, the platform ensures both high performance and operational simplicity.

+

Equally important, the framework is designed with flexibility and future evolution in mind. Its runtime-agnostic architecture enables seamless adoption of emerging inference engines, hardware accelerators, and optimization techniques without requiring platform redesign. This ensures that teams can continuously leverage advancements in the rapidly evolving LLM ecosystem while maintaining consistent operational workflows.

+

Ultimately, the goal of the platform is to make production-scale LLM deployment as seamless and reliable as traditional software deployment—allowing teams to focus on building intelligent applications rather than managing infrastructure complexity. By combining lifecycle automation, runtime optimization, and deep observability, the LLM Inference Framework provides a scalable foundation for delivering fast, cost-efficient, and production-ready LLM experiences.

+

Future Explorations

+

While we have achieved significant milestones in latency and throughput, the landscape of GenAI is evolving rapidly. Our roadmap focuses on increasing flexibility, reducing costs, and enhancing reliability for enterprise-grade workloads. Here is what we are building next:

+
    +
  • TPU Support: To diversify our hardware supply chain and further optimize cost-per-token, we are evaluating Google Cloud TPUs to bake it into our platform. By leveraging the JAX and PyTorch/XLA ecosystems, we aim to unlock the massive throughput potential of TPU v5e chips, particularly for our open-source Llama models. This will allow the hardware profiler to dynamically choose between NVIDIA GPUs and Google TPUs based on real-time availability and price-performance metrics.
  • +
  • Multi-LoRA Serving (Serverless Experience): Currently, deploying a fine-tuned model requires a dedicated GPU. We are building support for Multi-LoRA serving, which will allow us to serve hundreds of unique, fine-tuned adapters on top of a single frozen base model. This will drastically reduce costs for multi-tenant applications, enabling a "serverless" experience where specific fine-tunes are hot-swapped instantly per request.
  • +
  • Spot Instance Orchestration: To further optimize cloud costs, we are developing fault-tolerant mechanisms to run inference workloads on Spot Instances. By implementing aggressive checkpointing and seamless request draining, we aim to leverage cheaper, preemptible compute capacity without interrupting the user's streaming experience.
  • +
  • Semantic Caching Layer: We plan to move beyond standard Prefix Caching to implement Semantic Caching. By using a vector database to fetch responses for semantically similar queries (e.g., "How do I reset my password?" vs. "Password reset steps"), we can bypass the GPU entirely for repetitive queries, reducing latency to near-zero.
  • +
  • Context-Aware Autoscaling: Standard CPU/GPU utilization metrics are often insufficient signals for scaling LLMs. We are working on KV-cache pressure metrics for autoscaling. This ensures that we scale out before the memory fills up, preventing eviction-based slowdowns during traffic spikes.
  • +
  • Online Evaluation & Guardrails: We are integrating a lightweight "Trust Layer" into the proxy. This will allow for low-latency input/output filtering (Guardrails) and asynchronous "LLM-as-a-Judge" evaluation pipelines to monitor response quality in production, not just system health.
  • +
+ + \ No newline at end of file diff --git a/docs/blog/post-two/index.html b/docs/blog/post-two/index.html new file mode 100644 index 00000000..3d7c40d7 --- /dev/null +++ b/docs/blog/post-two/index.html @@ -0,0 +1,144 @@ + + + + + +Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2) | BharatMLStack + + + + + + + + +

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

· 7 min read
Bhawani Singh
Architect @ Meesho
Jigar Dave
Lead Software Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

+

By late 2022, we had built something we were truly proud of—a real-time ML serving system with a DAG-based executor, a feature store, and an interaction store powering key ranking and personalization models. It was a major milestone, the culmination of months of effort from data scientists, ML engineers, and backend teams. Our system was live, and we were ready to push the boundaries of experimentation. +And it worked. Mostly. +But soon, cracks appeared. Every new model needed custom feature retrieval logic, DAGs became dense and unmanageable, and scaling turned into a constant firefight. Costs surged, and infra bottlenecks slowed experimentation. Our system worked, but it wasn’t built for scale. +This is the story of how we tackled these challenges—building Inferflow for seamless feature retrieval, optimizing real-time infra, and cutting costs while scaling to millions of QPS.

+

The Cost of Success

+

Every new Ranker model required its own feature set, often pulling from different entities. Each addition meant:

+
    +
  • Adding new DAG nodes in IOP
  • +
  • Writing custom logic to fetch features from multiple sources (e.g., user, product, user × category)
  • +
  • Inferring intermediate features (e.g., extracting category from a product to fetch user × category data)
  • +
  • Optimizing I/O and dealing with the inevitable bugs
  • +
+

What began as clean DAGs soon turned into a tangled web of cross-dependent graphs. Every experimentation cycle meant new nodes, new dependencies, and slower iterations.

+

Scaling Pains (and Cassandra’s Limits)

+

At some point, we were hitting:

+
    +
  • 250–300K reads/sec
  • +
  • 1M writes/sec (during lean hours)
  • +
+

All of this ran on Cassandra. While its distributed architecture had been proven in production, operating large-scale clusters came with considerable infrastructure overhead. Our proof-of-concept (POC) demonstrated throughput of around 100K ops/sec, but as we scaled further, the challenges grew. Ensuring node health, optimizing compaction, and maintaining storage balance became increasingly demanding. We also observed latency spikes under heavy load, alongside a sharp increase in total cost of ownership.

+

Interaction Store Woes

+

Our interaction store was another ticking time bomb:

+
    +
  • 🚨 Clusters kept growing in size and cost
  • +
  • 🚨 Latency spikes became increasingly frequent
  • +
  • 🚨 The DMC proxy occasionally lost locality of nodes against shards, causing cross-node communication and degraded performance
  • +
+

Each time this happened, we had to manually rebalance shards just to restore stable latency, making operations unsustainable at scale.

+

Silver Linings

+

Despite the chaos, the system was live and delivering value:

+
    +
  • Real-time infrastructure was in production
  • +
  • Costs dropped by 60–70% compared to offline personalization
  • +
  • New experiments rolled out faster and more successfully
  • +
  • User engagement metrics improved
  • +
+

It wasn’t perfect. It was far from easy. But it worked—and that counted for a lot.

+

Round Two: Solving the Top 2 Bottlenecks

+

With the first-gen system stretched to its limits, we stepped back. Conversations with data scientists and backend engineers revealed three recurring pain points:

+
    +
  1. Coding feature retrieval logic for every new model was becoming unsustainable
  2. +
  3. ML scale was exploding—bringing rising infra costs with it
  4. +
  5. Real-time embedding search was the next big unlock
  6. +
+

We tackled them one by one—starting with the biggest pain point.

+

Problem 1: No-Code Feature Retrieval for Model Inference

+

We noticed a pattern: for personalized ranking, models needed features from:

+
    +
  • ✅ Product
  • +
  • ✅ User
  • +
  • ✅ User × Category
  • +
  • ✅ Region, cohort, sub-category, etc.
  • +
+

A key insight emerged: Entities that contribute features for a model always map back to the context entities.

+

MP Dag

+

With this, we designed Inferflow, a graph-driven feature retrieval and model orchestration system:

+
    +
  • 1️⃣ Inferflow takes a modelId and context IDs (e.g., userId, productIds)
  • +
  • 2️⃣ Loads a pre-defined feature retrieval graph from ZooKeeper
  • +
  • 3️⃣ Executes the graph to resolve entity relationships dynamically
  • +
  • 4️⃣ Outputs a 2D matrix of feature vectors
  • +
+

💡 The impact?

+
    +
  • 🚀 No more custom feature retrieval code—just graph updates in config
  • +
  • 🚀 Feature consistency across experiments
  • +
  • 🚀 Faster iteration cycles for ranking, fraud detection, and beyond
  • +
+

Here’s a visual example that shows how this graph plays out during execution. We further extended the graph to call multiple models as needed: +MP matrix +We built Inferflow in GoLang, using gRPC and Proto3 serialization for efficiency.

+

Problem 2: Scaling Without Breaking the Bank

+

With more ML use cases coming online, we needed to cut costs without compromising performance. We focused on:

+
    +
  • 🔹 Online Feature Store
  • +
  • 🔹 Interaction Store
  • +
+

Optimizing the Online Feature Store

+

Our costs were concentrated in:

+
    +
  • 📌 Database (Cassandra)
  • +
  • 📌 Cache (Redis)
  • +
  • 📌 Running Pods (Java services)
  • +
+

1️⃣ Replacing Cassandra with ScyllaDB +As we hit the operational limits of large Cassandra clusters, we transitioned to ScyllaDB, which offered a seamless drop-in replacement without major code changes. The switch brought significant benefits:

+
    +
  • Throughput: Matched or exceeded Cassandra's performance under identical workloads, even under high concurrency.
  • +
  • Latency: Achieved consistently lower P99 latencies due to ScyllaDB's shard-per-core architecture and better I/O utilization.
  • +
  • Cost Efficiency: Reduced infra footprint by ~70% through better CPU and memory efficiency, eliminating the need for over-provisioned nodes.
  • +
+

2️⃣ Finding the Right Cache +To reduce backend load and improve response times, we benchmarked multiple caching solutions—Memcached, KeyDB, and Dragonfly—under real production traffic patterns. Dragonfly stood out due to its robust architecture and operational simplicity:

+
    +
  • Data Skew Handling: Efficiently managed extreme key hotness and uneven access patterns without performance degradation.
  • +
  • Throughput: Delivered consistently high throughput, even with large object sizes and concurrent access.
  • +
  • Ease of Adoption: Acted as a drop-in Redis replacement with full protocol compatibility—no changes needed in application code or client libraries.
  • +
+

3️⃣ Moving to GoLang for Cost-Efficient Serving +Java services were memory-heavy—so we rewrote core services in GoLang. The results?

+

✅ Memory usage dropped by ~80% +✅ CPU utilization was significantly lower +✅ Faster, more efficient deployments

+

Optimizing the Interaction Store

+

We realized that we only need a user’s interaction data in Redis when they open the app. So, we implemented a tiered storage approach:

+
    +
  • 📌 Cold Tier (ScyllaDB)—Stores click, order, wishlist events
  • +
  • 📌 Hot Tier (Redis)—Loads a user’s past interactions only when they open the app
  • +
+

Smart Offloading: We introduced an inactivity tracker to detect when a user session ends. At that point, Redis data was flushed back to Scylla, reducing unnecessary writes.

+

InteractionStore

+

Results

+
    +
  • Online Feature Store hit 1M QPS for the first time during the 2023 Mega Blockbuster Sale—without breaking a sweat
  • +
  • Infra costs for Online Feature Store and Interaction Store dropped by ~60%
  • +
+

The Catch: Our ML Hosting Hit a Hard Limit

+

While planning for 2023 MBS, we ran into a critical scalability bottleneck:

+
    +
  • ❌ Insufficient compute availability in our region for ML instances
  • +
  • ❌ Couldn’t provision enough nodes to handle real-time inference at scale
  • +
+

This forced us to rethink where and how we hosted our models. The existing setup was great for prototyping—but it wasn’t built to handle the bursty, high-QPS demands of real-world production workloads.

+

Conclusion: From Firefighting to Future-Proofing

+

What started as an ambitious experiment turned into a real-time ML infrastructure that powered millions of requests per second. We battled scaling pains, rethought feature retrieval with Inferflow, and rebuilt our infra stack for efficiency—driving down costs while improving experimentation velocity. +But new challenges emerged. Our infrastructure could now handle scale, but our ML model hosting setup hit a hard limit. With compute availability bottlenecks threatening real-time inference, we faced a critical decision: how do we make model serving as scalable and cost-efficient as the rest of our stack? That’s the next piece of the puzzle—and the story of Part 3.

+ + \ No newline at end of file diff --git a/docs/blog/rss.xml b/docs/blog/rss.xml index 2d52444d..a5b41193 100644 --- a/docs/blog/rss.xml +++ b/docs/blog/rss.xml @@ -4,17 +4,640 @@ BharatMLStack Blog https://meesho.github.io/BharatMLStack/blog BharatMLStack Blog - Tue, 15 Nov 2022 00:00:00 GMT + Mon, 02 Jun 2025 00:00:00 GMT https://validator.w3.org/feed/docs/rss2.html https://github.com/jpmonette/feed en + + <![CDATA[LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale]]> + https://meesho.github.io/BharatMLStack/blog/post-five + https://meesho.github.io/BharatMLStack/blog/post-five + Mon, 02 Jun 2025 00:00:00 GMT + + BharatMLStack

+

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

+

Raw execution of Large Language Models is inherently expensive and memory-intensive. To achieve sub-second latency and high throughput, we implement a multi-layered optimization strategy that targets the entire inference stack—from memory management to kernel execution.

+

1. Advanced Memory Management: Paged & Prefix KV Caching

+

The most significant bottleneck in LLM inference is not always compute, but memory bandwidth—specifically managing the Key-Value (KV) cache.

+

Paged KV caching

+

Standard caching suffers from fragmentation. We use Paged KV caching, which operates similarly to an operating system's virtual memory: the KV cache is divided into non-contiguous blocks. This lets us serve larger batch sizes without running out of memory.

+

KV cache quantization

+

To further maximize available memory, we implement KV cache quantization (e.g., FP8). By compressing stored attention keys and values from 16-bit to 8-bit, we nearly double the effective context window capacity of the GPU, allowing longer conversations or larger batches without materially degrading quality.

+

Prefix caching (the "voice bot" optimizer)

+

For use cases like GenAI voice bots where the system prompt (e.g., "You are a helpful assistant...") is static across thousands of requests, we enable prefix caching.

+
    +
  • Impact: By reusing pre-computed KV states for common prefixes, we achieve a cache hit rate of ~90%. This reduces Time To First Token (TTFT) by skipping redundant computation of the system prompt.
  • +
+

2. Aggressive Quantization (INT4 AWQ & FP8)

+

Running models in their native 16-bit precision (BF16) restricts maximum batch size and throughput. We use quantization to shrink model weights without sacrificing accuracy.

+

INT4 AWQ (Activation-aware Weight Quantization)

+

For the Llama 3 family, we use AWQ to compress weights to 4 bits. This reduces model size by ~75%, allowing larger models to fit into L4 GPU memory and significantly improving token generation speed.

+

FP8 precision

+

For NVIDIA Hopper (H100) architectures, we are exploring FP8 quantization, leveraging native FP8 tensor cores to accelerate matrix multiplications while maintaining a higher dynamic range than integer quantization.

+
    +
  • Verification: We validate quantized models by comparing dot-product similarity of embeddings against the FP16 baseline, consistently achieving >99% similarity.
  • +
+

3. Kernel Fusion & Custom Plugins

+

To minimize overhead from launching thousands of small GPU operations, we fuse them into monolithic kernels using NVIDIA TensorRT plugins.

+
    +
  • Flash attention & FMHA: We enable Fused Multi-Head Attention (FMHA) combined with flash attention to reduce memory reads/writes.
  • +
  • GEMM plugins: We use specialized GEMM plugins to accelerate transformer linear layers.
  • +
  • Removing input padding: Instead of padding short sequences to match the longest, we remove input padding so the GPU processes only valid tokens.
  • +
+

4. Inflight (Continuous) Batching

+

Traditional static batching waits for all requests in a batch to finish before returning results—so one long response delays everyone else.

+

We implement inflight batching: as soon as one request completes, its slot is freed and filled by a new request from the queue. This keeps GPUs saturated and decouples latency of short queries from long ones.

+

5. Parallelism Strategies: Scaling Beyond One GPU

+

For large models (e.g., 70B+ parameters) that cannot fit into the VRAM of a single GPU, we use parallelism strategies.

+
    +
  • Tensor parallelism (TP): Split weight matrices across multiple GPUs (e.g., 4× L4 or 8× A100). Each GPU computes a shard and outputs are reduced at every layer.
  • +
  • Pipeline parallelism (PP): Split model layers across GPUs to pipeline compute (e.g., while one GPU computes later layers for Request A, another starts early layers for Request B).
  • +
+

6. Speculative Decoding

+

To reduce inter-token latency (ITL), we explore speculative decoding.

+
    +
  • Mechanism: A smaller, faster "draft" model speculatively generates a short token sequence (e.g., 5 tokens).
  • +
  • Verification: The larger target model verifies those tokens in one parallel forward pass. If correct, we effectively generate multiple tokens per large-model step; if not, we discard and regenerate. This is effective for predictable text, improving perceived generation speed.
  • +
+

Few Benchmarks

+

Below are a couple of representative use cases and performance numbers.

+

Search query rewriting

+
    +
  • LLM: Fine-tuned llama-3.2-1B
  • +
  • Input & output token length: ~10–20
  • +
  • Response type: Non-streaming
  • +
+
Inference runtimeHardwareMax requests/secMax p99 latency
TensorRT-LLM4 × L4 GPUs (multi-GPU)100095 ms
TensorRT-LLM1 × A100 40 GB GPU100069 ms
+

Voice bot query

+
    +
  • LLM: Llama-3.1-8B
  • +
  • Input token length: ~1900–2000
  • +
  • Output token length: ~200
  • +
  • Response type: Streaming
  • +
+
Inference runtimeConcurrencyp99 TTFT (ms)p99 ITL (ms)Token throughput (tokens/sec)Request throughput (req/sec)Hardware
TensorRT-LLM136.2722.7845.660.23L4
TensorRT-LLM249.8123.2189.370.45L4
TensorRT-LLM455.3336.62153.390.78L4
TensorRT-LLM866.539.11279.881.47L4
TensorRT-LLM16131.830.39547.82.77L4
TensorRT-LLM32277.2248.02925.74.78L4
TensorRT-LLM64498.5271.621,164.406.2L4
TensorRT-LLM128677.31120.371,445.187.69L4
TensorRT-LLM2561,926.31216.881,600.818.52L4
TensorRT-LLM121.179.24130.050.68A100
TensorRT-LLM225.789.21264.51.35A100
TensorRT-LLM428.5210.99437.692.27A100
TensorRT-LLM834.412.61760.493.96A100
TensorRT-LLM1668.0314.321,343.807.01A100
TensorRT-LLM32185.9616.822,287.3011.92A100
TensorRT-LLM64136.8721.173,625.2218.89A100
TensorRT-LLM128463.7834.154,456.5123.24A100
TensorRT-LLM256890.1259.185,188.2427.05A100
+

Conclusion

+

High-performance LLM inference is fundamentally a systems engineering problem: memory efficiency, kernel execution, batching strategy, and parallelism determine real-world latency and throughput. Techniques such as paged KV caching, aggressive quantization, kernel fusion, and inflight batching improve GPU utilization while reducing latency and memory pressure.

+

These optimizations enable the platform to deliver sub-second responses, sustain high concurrency, and efficiently serve both lightweight and long-context workloads. By continuously optimizing across the full inference stack, we keep LLM serving scalable, cost-efficient, and production-ready for real-time AI applications.

]]>
+ llm + vllm + tensorrt-llm + mlplatform + meesho + bharatmlstack +
+ + <![CDATA[Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving]]> + https://meesho.github.io/BharatMLStack/blog/post-three + https://meesho.github.io/BharatMLStack/blog/post-three + Sat, 29 Mar 2025 00:00:00 GMT + + BharatMLStack

+

Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving

+

Serving large language models in production introduces new challenges across infrastructure, performance optimization, and operational lifecycle management. The LLM Inference Platform addresses these challenges by providing a unified system for deploying and managing open-source and fine-tuned LLMs at scale.

+

The platform implements a complete LLMOps lifecycle — from model registration and automated compilation to deployment, runtime optimization, and monitoring. Designed as a self-service environment, users can onboard models directly from open repositories such as Hugging Face or upload custom fine-tuned models, and deploy them using a single-click workflow with no manual infrastructure or configuration steps required.

+

In addition to fully automated deployment, the platform allows users to select and apply custom inference optimization techniques — such as quantization strategies, batching configurations, and runtime-specific performance enhancements — enabling teams to balance latency, throughput, and cost based on their use case. The goal is to reduce operational friction while enabling high-performance, production-grade LLM inference.

+

Why LLM Inference Is not just bigger ML model serving

+

Large language model (LLM) inference introduces a fundamentally different set of challenges compared to traditional machine learning inference. While classical ML models typically perform a single forward pass to produce a fixed prediction, LLMs operate as autoregressive systems, generating outputs token by token based on previously generated context. This difference dramatically changes how inference systems must be designed, optimized, and scaled.

+

Autoregressive Generation and Sequential Computation:

+

Unlike traditional models such as classifiers or recommenders — where inference cost is relatively constant — LLMs generate responses incrementally. Each new token depends on all previously generated tokens, making inference inherently sequential and dynamic. This means latency and compute requirements vary significantly depending on prompt length and output size, introducing complexity in scheduling and resource allocation. +Because tokens cannot be generated fully in parallel during decoding, GPUs may become underutilized without specialized batching and scheduling strategies. This has led to the development of dedicated LLM inference engines optimized for token-level execution.

+

Prefill and Decode Phases:

+

LLM inference typically consists of two distinct stages:

+
    +
  • Prefill phase — the model processes the input prompt and builds internal representations. This stage is compute-heavy and highly parallelizable.
  • +
  • Decode phase — the model generates tokens sequentially, predicting one token at a time using previously generated context.
  • +
+

The decode stage often becomes memory-bound rather than compute-bound, which creates new performance bottlenecks compared to traditional ML workloads.

+

Context Management and KV Caching:

+

Another fundamental difference lies in how LLMs maintain context. Transformer-based models rely on attention mechanisms that require access to past token representations. To avoid recomputing these representations repeatedly, inference engines use key-value (KV) caching, which stores intermediate activations from previous tokens. +KV caching significantly improves performance by eliminating redundant computation, but it introduces new challenges:

+
    +
  • Memory consumption grows with sequence length and batch size
  • +
  • GPU memory becomes a critical bottleneck
  • +
  • Efficient memory management becomes essential for scaling concurrent requests
  • +
+

This tradeoff between compute efficiency and memory usage is unique to LLM inference workloads.

+

Dynamic and Irregular Workloads:

+

Traditional ML inference typically operates on fixed-size inputs with predictable latency. In contrast, LLM requests vary widely in prompt length, output length, and runtime behavior. As a result:

+
    +
  • Batch sizes must be dynamic rather than static
  • +
  • Requests may enter and leave batches asynchronously
  • +
  • Scheduling systems must continuously rebalance workloads to maximize GPU utilization
  • +
+

These characteristics require specialized serving architectures that differ significantly from standard ML serving pipelines.

+

Streaming and User Experience Constraints:

+

Another distinguishing factor is the expectation of real-time streaming responses. Instead of returning a single output, LLM systems often stream tokens to users as they are generated. +Because of these differences — sequential generation, growing memory requirements, dynamic workloads, and streaming constraints — LLM inference cannot be treated as a simple extension of existing ML serving systems. Production platforms must incorporate specialized runtime engines, advanced optimization techniques, and observability tailored specifically to LLM workloads.

+

LLMOps: High-Level Architecture

+

LLM Architecture

+

The LLM Inference Framework is designed as a fully automated, end-to-end system for deploying and operating open-source and fine-tuned large language models at scale. The architecture abstracts the complexity of model optimization, hardware selection, deployment, and runtime management into a unified workflow that enables users to move from raw model weights to production-ready inference endpoints with minimal manual intervention.

+

Our LLM Inference Framework is architected not just as a serving engine, but as a complete lifecycle management system. As illustrated in the high-level design below, the platform automates the journey of a model through seven distinct stages, ensuring reproducibility, performance, and scalability.

+
    +
  1. +

    Onboarding & Registration (The Source of Truth)

    +

    The lifecycle begins with the Data Scientist or engineer.

    +
      +
    • Model Ingestion: Users onboard models—whether open-source (Hugging Face, NeMo) or internally fine-tuned—via the Truffle Box SDK/UI.
    • +
    • LLM + Prompt Registry: Unlike traditional systems that only track model weights, our registry is a unified control plane. It stores both the Model Artifacts and the Prompt Templates. This allows Data Scientists to register and version-control prompts (e.g., "customer_support_v2") independently of the application code.
    • +
    +
  2. +
  3. +

    The "Black Box" Build Engine

    +

    Once a model is registered, the Automated LLM Compiler + Quantizer Module kicks off a background job on ephemeral GPU resources.

    +
      +
    • Transformation: The raw model is converted into a TRT-LLM Checkpoint.
    • +
    • Quantization: The system automatically applies quantization algorithms (like INT4 AWQ or FP8) to reduce memory footprint.
    • +
    • Engine Building: Finally, it compiles a highly optimized TRT Engine specifically tuned for the target hardware.
    • +
    +
  4. +
  5. +

    Intelligent Profiling & Validation

    +

    Before deployment, the new engine passes through the Hardware & Inference Runtime Profiler.

    +
      +
    • Benchmarking: This module empirically tests the engine against various hardware configurations (L4 vs. A100) and runtimes (TRT-LLM vs. vLLM).
    • +
    • Optimization: It recommends the optimal configuration that meets latency SLAs (Time-To-First-Token) while minimizing cost.
    • +
    +
  6. +
  7. +

    Smart Artifact Generation & Distribution

    +

    To solve the Kubernetes "Cold Start" problem, the LLM Serving Artifacts Generation module packages the model using a bifurcated strategy:

    +
      +
    • Standard Models: Artifacts are uploaded to Cloud Storage (GCS) and downloaded by pods at startup.
    • +
    • Very Large Models: For massive models (>8GB) where network downloads are too slow, the system pre-caches the model onto Secondary Boot Disks. These disks are attached directly to new GPU nodes during autoscaling, eliminating download wait times.
    • +
    +
  8. +
  9. +

    Image Streaming & Deployment

    +

    Simultaneously, the inference runtime container images are pulled from the Artifact Registry.

    +
      +
    • Image Streaming: We utilize container image streaming to allow pods to start initializing while the massive Triton/Dynamo container layers are still downloading, further shaving seconds off the startup time. link
    • +
    +
  10. +
  11. +

    The Inference Runtime (Kubernetes)

    +

    The workload lands on Kubernetes with Autoscaling.

    +
      +
    • Dynamic Backends: Depending on the profile generated in Stage 3, the pod initializes either TensorRT-LLM (for throughput) or vLLM (for flexibility), or spins up a Dynamo worker for distributed inference.
    • +
    • Data Loading: The pod either downloads the model from Cloud Storage or mounts the pre-warmed Secondary Boot Disk ("Pull from Disk").
    • +
    +
  12. +
  13. +

    Client Interaction & Observability

    +

    Finally, the LLM Inference Client executes the request.

    +
      +
    • Prompt Injection: The client pulls the specific prompt template ID from the Registry, ensuring the exact versioned instructions are used.
    • +
    • Streaming Response: The request is sent via gRPC, and tokens are streamed back to the user in real-time.
    • +
    +
  14. +
  15. +

    Observability: Monitoring the Pulse of GenAI

    +

    In traditional microservices, success is measured by CPU utilization and request latency (p99). For Large Language Models, these metrics are insufficient. A user doesn't care if the GPU is at 80% utilization; they care about how fast the first word appears and how smoothly the rest of the sentence follows.

    +

    To capture the true user experience, our platform instrumentation focuses on three critical LLM-specific metrics:

    +
      +
    1. +

      Time to First Token (TTFT)

      +
        +
      • Definition: TTFT measures the time elapsed from the moment a request is received until the very first token is generated and streamed back to the user.
      • +
      • Why it matters: This represents the "Prefill Phase" latency—the time the model takes to process the input prompt and load weights. A high TTFT makes the application feel unresponsive or "hung."
      • +
      • Optimization: We closely monitor TTFT to ensure our Prefix Caching is effective (aiming for high cache hitrates), which drastically lowers this metric by skipping redundant prompt processing.
      • +
      +
    2. +
    3. +

      Inter-Token Latency (ITL)

      +
        +
      • Definition: ITL measures the average time interval between the generation of consecutive tokens during the "Decode Phase".
      • +
      • Why it matters: This defines the "perceived speed" of reading. Even if the first token is fast (low TTFT), high ITL makes the text generation look "jerky" or slow to the user.
      • +
      • Benchmarks: In our testing with Llama 3.1, we track p99 ITL to ensure it stays below human reading speeds to maintain a natural conversational flow.
      • +
      +
    4. +
    5. +

      Token Throughput vs. Request Throughput

      +
        +
      • We distinguish between two types of throughput to balance system efficiency with user load:
      • +
      • Token Throughput (tokens/sec): The total number of tokens generated across all concurrent requests. This measures the raw compute efficiency of the GPU and the effectiveness of batching.
      • +
      • Request Throughput (req/sec): The number of distinct user queries served per second. We use this to determine autoscaling thresholds, ensuring we scale out before the queue depth impacts ITL.
      • +
      +
    6. +
    7. +

      The Monitoring Stack

      +
        +
      • Real-time Dashboards: We utilize Grafana to visualize these streaming metrics in real-time, allowing on-call engineers to spot "slow generation" incidents that generic "500 error" alerts would miss.
      • +
      • Request Tracing: Since Triton Inference Server does not log request payloads by default, we integrate a Helix Client to asynchronously publish request logs to Log Tables. This allows us to trace a specific "slow" request back to its prompt to understand if a complex input caused the latency spike.
      • +
      +
    8. +
    +
  16. +
+

Supported Inference backends (TensorRT LLM, Dynamo & vLLM)

+

Tailored for the Use Case: We do not believe in a "one-size-fits-all" approach to inference. Different use cases—whether a real-time voice bot requiring ultra-lowsub-second latency or a massive reasoning task requiring huge context windows—demand different runtime characteristics. Our platform is designed to be runtime-agnostic, allowing us to automatically select and tailor the best engine based on the specific requirements of the application:

+
    +
  1. +

    TensorRT-LLM: The High-Performance Standard

    +

    Suitable for: High-throughput production workloads where latency is critical (e.g., customer support chat, real-time voice bots).

    +

    TensorRT-LLM serves as our default backend for these scenarios. Our internal benchmarks on Llama 3.1 and 3.2 models demonstrated that a tuned TensorRT-LLM engine significantly outperforms standard runtimes, especially when utilizing INT4 AWQ and FP8 quantization .

    +

    Key optimizations we tailor for these high-load cases include:

    +
      +
    • Optimized execution via TensorRT engine compilation
    • +
    • Quantization-aware execution for reduced memory usage and improved throughput
    • +
    • Inflight Batching: Allowing requests to be processed continuously without waiting for the entire batch to finish, drastically improving GPU utilization .
    • +
    • Custom Plugins: Enabling specific NVIDIA plugins like the GEMM plugin and GPT Attention plugin to accelerate matrix multiplications and attention mechanisms .
    • +
    +
  2. +
  3. +

    Dynamo: Distributed Inference for Reasoning Models

    +

    Suitable for: Very large "reasoning" models (70B+) or scenarios requiring massive context windows where a single GPU's memory is insufficient.

    +

    For these memory-bound tasks, we utilize Dynamo, a low-latency distributed inference framework . Unlike monolithic servers, Dynamo disaggregates the inference process to scale resources horizontally:

    +
      +
    • KV Aware Routing: A specialized router directs requests to workers that already hold the relevant Key-Value (KV) cache, minimizing redundant computation .
    • +
    • Prefill vs. Decode Split: The workload is divided into Prefill Workers (processing the prompt) and Decode Workers (generating tokens), allowing us to scale the compute-heavy "reading" phase independently from the memory-heavy "writing" phase .
    • +
    • Distributed execution across multiple GPU resources
    • +
    +
  4. +
  5. +

    vLLM: The Flexible Baseline

    +

    Suitable for: Rapid prototyping, testing new model architectures, or low-traffic internal tools where ease of deployment outweighs raw throughput.

    +

    While TensorRT-LLM is optimized for maximum speed, vLLM provides a robust and flexible baseline .

    +
      +
    • High throughput through dynamic batching and efficient memory utilization
    • +
    • Paged KV cache management for handling long contexts and concurrent requests
    • +
    • Strong support for open-source model ecosystems
    • +
    • Rapid Adoption: It allows us to onboard new model architectures immediately without waiting for a custom TensorRT build.
    • +
    • Benchmarking Insight: In our internal tests, vLLM provided a strong baseline but often lacked the specific max-token optimizations present in our custom TRT engines . We use it strategically for initial testing before committing to a full TensorRT optimization pipeline.
    • +
    +
  6. +
+

Conclusion

+

Large language model inference introduces a fundamentally new class of infrastructure challenges—where performance is governed not just by raw compute, but by memory efficiency, intelligent scheduling, runtime specialization, and lifecycle automation. Unlike traditional ML serving, LLM inference requires systems that understand token-level execution, manage rapidly growing context state, and continuously balance latency, throughput, and cost under highly dynamic workloads.

+

The LLM Inference Framework addresses these challenges by transforming inference into a fully automated, reproducible lifecycle—from model onboarding and compilation to deployment, optimization, and observability. By integrating automated quantization and engine compilation, intelligent runtime selection, cold-start mitigation strategies, and LLM-specific observability metrics such as Time-to-First-Token and Inter-Token Latency, the platform ensures both high performance and operational simplicity.

+

Equally important, the framework is designed with flexibility and future evolution in mind. Its runtime-agnostic architecture enables seamless adoption of emerging inference engines, hardware accelerators, and optimization techniques without requiring platform redesign. This ensures that teams can continuously leverage advancements in the rapidly evolving LLM ecosystem while maintaining consistent operational workflows.

+

Ultimately, the goal of the platform is to make production-scale LLM deployment as seamless and reliable as traditional software deployment—allowing teams to focus on building intelligent applications rather than managing infrastructure complexity. By combining lifecycle automation, runtime optimization, and deep observability, the LLM Inference Framework provides a scalable foundation for delivering fast, cost-efficient, and production-ready LLM experiences.

+

Future Explorations

+

While we have achieved significant milestones in latency and throughput, the landscape of GenAI is evolving rapidly. Our roadmap focuses on increasing flexibility, reducing costs, and enhancing reliability for enterprise-grade workloads. Here is what we are building next:

+
    +
  • TPU Support: To diversify our hardware supply chain and further optimize cost-per-token, we are evaluating Google Cloud TPUs to bake it into our platform. By leveraging the JAX and PyTorch/XLA ecosystems, we aim to unlock the massive throughput potential of TPU v5e chips, particularly for our open-source Llama models. This will allow the hardware profiler to dynamically choose between NVIDIA GPUs and Google TPUs based on real-time availability and price-performance metrics.
  • +
  • Multi-LoRA Serving (Serverless Experience): Currently, deploying a fine-tuned model requires a dedicated GPU. We are building support for Multi-LoRA serving, which will allow us to serve hundreds of unique, fine-tuned adapters on top of a single frozen base model. This will drastically reduce costs for multi-tenant applications, enabling a "serverless" experience where specific fine-tunes are hot-swapped instantly per request.
  • +
  • Spot Instance Orchestration: To further optimize cloud costs, we are developing fault-tolerant mechanisms to run inference workloads on Spot Instances. By implementing aggressive checkpointing and seamless request draining, we aim to leverage cheaper, preemptible compute capacity without interrupting the user's streaming experience.
  • +
  • Semantic Caching Layer: We plan to move beyond standard Prefix Caching to implement Semantic Caching. By using a vector database to fetch responses for semantically similar queries (e.g., "How do I reset my password?" vs. "Password reset steps"), we can bypass the GPU entirely for repetitive queries, reducing latency to near-zero.
  • +
  • Context-Aware Autoscaling: Standard CPU/GPU utilization metrics are often insufficient signals for scaling LLMs. We are working on KV-cache pressure metrics for autoscaling. This ensures that we scale out before the memory fills up, preventing eviction-based slowdowns during traffic spikes.
  • +
  • Online Evaluation & Guardrails: We are integrating a lightweight "Trust Layer" into the proxy. This will allow for low-latency input/output filtering (Guardrails) and asynchronous "LLM-as-a-Judge" evaluation pipelines to monitor response quality in production, not just system health.
  • +
]]>
+ llm + vllm + tensorrt-llm + mlplatform + meesho + bharatmlstack +
+ + <![CDATA[Cracking the Code: Scaling Model Inference & Real-Time Embedding Search]]> + https://meesho.github.io/BharatMLStack/blog/post-three + https://meesho.github.io/BharatMLStack/blog/post-three + Tue, 21 May 2024 00:00:00 GMT + + BharatMLStack

+

Designing a Production-Grade LLM Inference Platform: From Model Weights to Scalable GPU Serving

+

Serving large language models in production introduces new challenges across infrastructure, performance optimization, and operational lifecycle management. The LLM Inference Platform addresses these challenges by providing a unified system for deploying and managing open-source and fine-tuned LLMs at scale.

+

The platform implements a complete LLMOps lifecycle — from model registration and automated compilation to deployment, runtime optimization, and monitoring. Designed as a self-service environment, users can onboard models directly from open repositories such as Hugging Face or upload custom fine-tuned models, and deploy them using a single-click workflow with no manual infrastructure or configuration steps required.

+

In addition to fully automated deployment, the platform allows users to select and apply custom inference optimization techniques — such as quantization strategies, batching configurations, and runtime-specific performance enhancements — enabling teams to balance latency, throughput, and cost based on their use case. The goal is to reduce operational friction while enabling high-performance, production-grade LLM inference.

+

Why LLM Inference Is not just bigger ML model serving

+

Large language model (LLM) inference introduces a fundamentally different set of challenges compared to traditional machine learning inference. While classical ML models typically perform a single forward pass to produce a fixed prediction, LLMs operate as autoregressive systems, generating outputs token by token based on previously generated context. This difference dramatically changes how inference systems must be designed, optimized, and scaled.

+

Autoregressive Generation and Sequential Computation:

+

Unlike traditional models such as classifiers or recommenders — where inference cost is relatively constant — LLMs generate responses incrementally. Each new token depends on all previously generated tokens, making inference inherently sequential and dynamic. This means latency and compute requirements vary significantly depending on prompt length and output size, introducing complexity in scheduling and resource allocation. +Because tokens cannot be generated fully in parallel during decoding, GPUs may become underutilized without specialized batching and scheduling strategies. This has led to the development of dedicated LLM inference engines optimized for token-level execution.

+

Prefill and Decode Phases:

+

LLM inference typically consists of two distinct stages:

+
    +
  • Prefill phase — the model processes the input prompt and builds internal representations. This stage is compute-heavy and highly parallelizable.
  • +
  • Decode phase — the model generates tokens sequentially, predicting one token at a time using previously generated context.
  • +
+

The decode stage often becomes memory-bound rather than compute-bound, which creates new performance bottlenecks compared to traditional ML workloads.

+

Context Management and KV Caching:

+

Another fundamental difference lies in how LLMs maintain context. Transformer-based models rely on attention mechanisms that require access to past token representations. To avoid recomputing these representations repeatedly, inference engines use key-value (KV) caching, which stores intermediate activations from previous tokens. +KV caching significantly improves performance by eliminating redundant computation, but it introduces new challenges:

+
    +
  • Memory consumption grows with sequence length and batch size
  • +
  • GPU memory becomes a critical bottleneck
  • +
  • Efficient memory management becomes essential for scaling concurrent requests
  • +
+

This tradeoff between compute efficiency and memory usage is unique to LLM inference workloads.

+

Dynamic and Irregular Workloads:

+

Traditional ML inference typically operates on fixed-size inputs with predictable latency. In contrast, LLM requests vary widely in prompt length, output length, and runtime behavior. As a result:

+
    +
  • Batch sizes must be dynamic rather than static
  • +
  • Requests may enter and leave batches asynchronously
  • +
  • Scheduling systems must continuously rebalance workloads to maximize GPU utilization
  • +
+

These characteristics require specialized serving architectures that differ significantly from standard ML serving pipelines.

+

Streaming and User Experience Constraints:

+

Another distinguishing factor is the expectation of real-time streaming responses. Instead of returning a single output, LLM systems often stream tokens to users as they are generated. +Because of these differences — sequential generation, growing memory requirements, dynamic workloads, and streaming constraints — LLM inference cannot be treated as a simple extension of existing ML serving systems. Production platforms must incorporate specialized runtime engines, advanced optimization techniques, and observability tailored specifically to LLM workloads.

+

LLMOps: High-Level Architecture

+

LLM Architecture

+

The LLM Inference Framework is designed as a fully automated, end-to-end system for deploying and operating open-source and fine-tuned large language models at scale. The architecture abstracts the complexity of model optimization, hardware selection, deployment, and runtime management into a unified workflow that enables users to move from raw model weights to production-ready inference endpoints with minimal manual intervention.

+

Our LLM Inference Framework is architected not just as a serving engine, but as a complete lifecycle management system. As illustrated in the high-level design below, the platform automates the journey of a model through seven distinct stages, ensuring reproducibility, performance, and scalability.

+
    +
  1. +

    Onboarding & Registration (The Source of Truth)

    +

    The lifecycle begins with the Data Scientist or engineer.

    +
      +
    • Model Ingestion: Users onboard models—whether open-source (Hugging Face, NeMo) or internally fine-tuned—via the Truffle Box SDK/UI.
    • +
    • LLM + Prompt Registry: Unlike traditional systems that only track model weights, our registry is a unified control plane. It stores both the Model Artifacts and the Prompt Templates. This allows Data Scientists to register and version-control prompts (e.g., "customer_support_v2") independently of the application code.
    • +
    +
  2. +
  3. +

    The "Black Box" Build Engine

    +

    Once a model is registered, the Automated LLM Compiler + Quantizer Module kicks off a background job on ephemeral GPU resources.

    +
      +
    • Transformation: The raw model is converted into a TRT-LLM Checkpoint.
    • +
    • Quantization: The system automatically applies quantization algorithms (like INT4 AWQ or FP8) to reduce memory footprint.
    • +
    • Engine Building: Finally, it compiles a highly optimized TRT Engine specifically tuned for the target hardware.
    • +
    +
  4. +
  5. +

    Intelligent Profiling & Validation

    +

    Before deployment, the new engine passes through the Hardware & Inference Runtime Profiler.

    +
      +
    • Benchmarking: This module empirically tests the engine against various hardware configurations (L4 vs. A100) and runtimes (TRT-LLM vs. vLLM).
    • +
    • Optimization: It recommends the optimal configuration that meets latency SLAs (Time-To-First-Token) while minimizing cost.
    • +
    +
  6. +
  7. +

    Smart Artifact Generation & Distribution

    +

    To solve the Kubernetes "Cold Start" problem, the LLM Serving Artifacts Generation module packages the model using a bifurcated strategy:

    +
      +
    • Standard Models: Artifacts are uploaded to Cloud Storage (GCS) and downloaded by pods at startup.
    • +
    • Very Large Models: For massive models (>8GB) where network downloads are too slow, the system pre-caches the model onto Secondary Boot Disks. These disks are attached directly to new GPU nodes during autoscaling, eliminating download wait times.
    • +
    +
  8. +
  9. +

    Image Streaming & Deployment

    +

    Simultaneously, the inference runtime container images are pulled from the Artifact Registry.

    +
      +
    • Image Streaming: We utilize container image streaming to allow pods to start initializing while the massive Triton/Dynamo container layers are still downloading, further shaving seconds off the startup time. link
    • +
    +
  10. +
  11. +

    The Inference Runtime (Kubernetes)

    +

    The workload lands on Kubernetes with Autoscaling.

    +
      +
    • Dynamic Backends: Depending on the profile generated in Stage 3, the pod initializes either TensorRT-LLM (for throughput) or vLLM (for flexibility), or spins up a Dynamo worker for distributed inference.
    • +
    • Data Loading: The pod either downloads the model from Cloud Storage or mounts the pre-warmed Secondary Boot Disk ("Pull from Disk").
    • +
    +
  12. +
  13. +

    Client Interaction & Observability

    +

    Finally, the LLM Inference Client executes the request.

    +
      +
    • Prompt Injection: The client pulls the specific prompt template ID from the Registry, ensuring the exact versioned instructions are used.
    • +
    • Streaming Response: The request is sent via gRPC, and tokens are streamed back to the user in real-time.
    • +
    +
  14. +
  15. +

    Observability: Monitoring the Pulse of GenAI

    +

    In traditional microservices, success is measured by CPU utilization and request latency (p99). For Large Language Models, these metrics are insufficient. A user doesn't care if the GPU is at 80% utilization; they care about how fast the first word appears and how smoothly the rest of the sentence follows.

    +

    To capture the true user experience, our platform instrumentation focuses on three critical LLM-specific metrics:

    +
      +
    1. +

      Time to First Token (TTFT)

      +
        +
      • Definition: TTFT measures the time elapsed from the moment a request is received until the very first token is generated and streamed back to the user.
      • +
      • Why it matters: This represents the "Prefill Phase" latency—the time the model takes to process the input prompt and load weights. A high TTFT makes the application feel unresponsive or "hung."
      • +
      • Optimization: We closely monitor TTFT to ensure our Prefix Caching is effective (aiming for high cache hitrates), which drastically lowers this metric by skipping redundant prompt processing.
      • +
      +
    2. +
    3. +

      Inter-Token Latency (ITL)

      +
        +
      • Definition: ITL measures the average time interval between the generation of consecutive tokens during the "Decode Phase".
      • +
      • Why it matters: This defines the "perceived speed" of reading. Even if the first token is fast (low TTFT), high ITL makes the text generation look "jerky" or slow to the user.
      • +
      • Benchmarks: In our testing with Llama 3.1, we track p99 ITL to ensure it stays below human reading speeds to maintain a natural conversational flow.
      • +
      +
    4. +
    5. +

      Token Throughput vs. Request Throughput

      +
        +
      • We distinguish between two types of throughput to balance system efficiency with user load:
      • +
      • Token Throughput (tokens/sec): The total number of tokens generated across all concurrent requests. This measures the raw compute efficiency of the GPU and the effectiveness of batching.
      • +
      • Request Throughput (req/sec): The number of distinct user queries served per second. We use this to determine autoscaling thresholds, ensuring we scale out before the queue depth impacts ITL.
      • +
      +
    6. +
    7. +

      The Monitoring Stack

      +
        +
      • Real-time Dashboards: We utilize Grafana to visualize these streaming metrics in real-time, allowing on-call engineers to spot "slow generation" incidents that generic "500 error" alerts would miss.
      • +
      • Request Tracing: Since Triton Inference Server does not log request payloads by default, we integrate a Helix Client to asynchronously publish request logs to Log Tables. This allows us to trace a specific "slow" request back to its prompt to understand if a complex input caused the latency spike.
      • +
      +
    8. +
    +
  16. +
+

Supported Inference backends (TensorRT LLM, Dynamo & vLLM)

+

Tailored for the Use Case: We do not believe in a "one-size-fits-all" approach to inference. Different use cases—whether a real-time voice bot requiring ultra-lowsub-second latency or a massive reasoning task requiring huge context windows—demand different runtime characteristics. Our platform is designed to be runtime-agnostic, allowing us to automatically select and tailor the best engine based on the specific requirements of the application:

+
    +
  1. +

    TensorRT-LLM: The High-Performance Standard

    +

    Suitable for: High-throughput production workloads where latency is critical (e.g., customer support chat, real-time voice bots).

    +

    TensorRT-LLM serves as our default backend for these scenarios. Our internal benchmarks on Llama 3.1 and 3.2 models demonstrated that a tuned TensorRT-LLM engine significantly outperforms standard runtimes, especially when utilizing INT4 AWQ and FP8 quantization .

    +

    Key optimizations we tailor for these high-load cases include:

    +
      +
    • Optimized execution via TensorRT engine compilation
    • +
    • Quantization-aware execution for reduced memory usage and improved throughput
    • +
    • Inflight Batching: Allowing requests to be processed continuously without waiting for the entire batch to finish, drastically improving GPU utilization .
    • +
    • Custom Plugins: Enabling specific NVIDIA plugins like the GEMM plugin and GPT Attention plugin to accelerate matrix multiplications and attention mechanisms .
    • +
    +
  2. +
  3. +

    Dynamo: Distributed Inference for Reasoning Models

    +

    Suitable for: Very large "reasoning" models (70B+) or scenarios requiring massive context windows where a single GPU's memory is insufficient.

    +

    For these memory-bound tasks, we utilize Dynamo, a low-latency distributed inference framework . Unlike monolithic servers, Dynamo disaggregates the inference process to scale resources horizontally:

    +
      +
    • KV Aware Routing: A specialized router directs requests to workers that already hold the relevant Key-Value (KV) cache, minimizing redundant computation .
    • +
    • Prefill vs. Decode Split: The workload is divided into Prefill Workers (processing the prompt) and Decode Workers (generating tokens), allowing us to scale the compute-heavy "reading" phase independently from the memory-heavy "writing" phase .
    • +
    • Distributed execution across multiple GPU resources
    • +
    +
  4. +
  5. +

    vLLM: The Flexible Baseline

    +

    Suitable for: Rapid prototyping, testing new model architectures, or low-traffic internal tools where ease of deployment outweighs raw throughput.

    +

    While TensorRT-LLM is optimized for maximum speed, vLLM provides a robust and flexible baseline .

    +
      +
    • High throughput through dynamic batching and efficient memory utilization
    • +
    • Paged KV cache management for handling long contexts and concurrent requests
    • +
    • Strong support for open-source model ecosystems
    • +
    • Rapid Adoption: It allows us to onboard new model architectures immediately without waiting for a custom TensorRT build.
    • +
    • Benchmarking Insight: In our internal tests, vLLM provided a strong baseline but often lacked the specific max-token optimizations present in our custom TRT engines . We use it strategically for initial testing before committing to a full TensorRT optimization pipeline.
    • +
    +
  6. +
+

Conclusion

+

Large language model inference introduces a fundamentally new class of infrastructure challenges—where performance is governed not just by raw compute, but by memory efficiency, intelligent scheduling, runtime specialization, and lifecycle automation. Unlike traditional ML serving, LLM inference requires systems that understand token-level execution, manage rapidly growing context state, and continuously balance latency, throughput, and cost under highly dynamic workloads.

+

The LLM Inference Framework addresses these challenges by transforming inference into a fully automated, reproducible lifecycle—from model onboarding and compilation to deployment, optimization, and observability. By integrating automated quantization and engine compilation, intelligent runtime selection, cold-start mitigation strategies, and LLM-specific observability metrics such as Time-to-First-Token and Inter-Token Latency, the platform ensures both high performance and operational simplicity.

+

Equally important, the framework is designed with flexibility and future evolution in mind. Its runtime-agnostic architecture enables seamless adoption of emerging inference engines, hardware accelerators, and optimization techniques without requiring platform redesign. This ensures that teams can continuously leverage advancements in the rapidly evolving LLM ecosystem while maintaining consistent operational workflows.

+

Ultimately, the goal of the platform is to make production-scale LLM deployment as seamless and reliable as traditional software deployment—allowing teams to focus on building intelligent applications rather than managing infrastructure complexity. By combining lifecycle automation, runtime optimization, and deep observability, the LLM Inference Framework provides a scalable foundation for delivering fast, cost-efficient, and production-ready LLM experiences.

+

Future Explorations

+

While we have achieved significant milestones in latency and throughput, the landscape of GenAI is evolving rapidly. Our roadmap focuses on increasing flexibility, reducing costs, and enhancing reliability for enterprise-grade workloads. Here is what we are building next:

+
    +
  • TPU Support: To diversify our hardware supply chain and further optimize cost-per-token, we are evaluating Google Cloud TPUs to bake it into our platform. By leveraging the JAX and PyTorch/XLA ecosystems, we aim to unlock the massive throughput potential of TPU v5e chips, particularly for our open-source Llama models. This will allow the hardware profiler to dynamically choose between NVIDIA GPUs and Google TPUs based on real-time availability and price-performance metrics.
  • +
  • Multi-LoRA Serving (Serverless Experience): Currently, deploying a fine-tuned model requires a dedicated GPU. We are building support for Multi-LoRA serving, which will allow us to serve hundreds of unique, fine-tuned adapters on top of a single frozen base model. This will drastically reduce costs for multi-tenant applications, enabling a "serverless" experience where specific fine-tunes are hot-swapped instantly per request.
  • +
  • Spot Instance Orchestration: To further optimize cloud costs, we are developing fault-tolerant mechanisms to run inference workloads on Spot Instances. By implementing aggressive checkpointing and seamless request draining, we aim to leverage cheaper, preemptible compute capacity without interrupting the user's streaming experience.
  • +
  • Semantic Caching Layer: We plan to move beyond standard Prefix Caching to implement Semantic Caching. By using a vector database to fetch responses for semantically similar queries (e.g., "How do I reset my password?" vs. "Password reset steps"), we can bypass the GPU entirely for repetitive queries, reducing latency to near-zero.
  • +
  • Context-Aware Autoscaling: Standard CPU/GPU utilization metrics are often insufficient signals for scaling LLMs. We are working on KV-cache pressure metrics for autoscaling. This ensures that we scale out before the memory fills up, preventing eviction-based slowdowns during traffic spikes.
  • +
  • Online Evaluation & Guardrails: We are integrating a lightweight "Trust Layer" into the proxy. This will allow for low-latency input/output filtering (Guardrails) and asynchronous "LLM-as-a-Judge" evaluation pipelines to monitor response quality in production, not just system health.
  • +
]]>
+ model-inference + embedding-search + mlplatform + meesho + bharatmlstack +
+ + <![CDATA[Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)]]> + https://meesho.github.io/BharatMLStack/blog/post-two + https://meesho.github.io/BharatMLStack/blog/post-two + Mon, 10 Apr 2023 00:00:00 GMT + + BharatMLStack

+

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

+

By late 2022, we had built something we were truly proud of—a real-time ML serving system with a DAG-based executor, a feature store, and an interaction store powering key ranking and personalization models. It was a major milestone, the culmination of months of effort from data scientists, ML engineers, and backend teams. Our system was live, and we were ready to push the boundaries of experimentation. +And it worked. Mostly. +But soon, cracks appeared. Every new model needed custom feature retrieval logic, DAGs became dense and unmanageable, and scaling turned into a constant firefight. Costs surged, and infra bottlenecks slowed experimentation. Our system worked, but it wasn’t built for scale. +This is the story of how we tackled these challenges—building Inferflow for seamless feature retrieval, optimizing real-time infra, and cutting costs while scaling to millions of QPS.

+

The Cost of Success

+

Every new Ranker model required its own feature set, often pulling from different entities. Each addition meant:

+
    +
  • Adding new DAG nodes in IOP
  • +
  • Writing custom logic to fetch features from multiple sources (e.g., user, product, user × category)
  • +
  • Inferring intermediate features (e.g., extracting category from a product to fetch user × category data)
  • +
  • Optimizing I/O and dealing with the inevitable bugs
  • +
+

What began as clean DAGs soon turned into a tangled web of cross-dependent graphs. Every experimentation cycle meant new nodes, new dependencies, and slower iterations.

+

Scaling Pains (and Cassandra’s Limits)

+

At some point, we were hitting:

+
    +
  • 250–300K reads/sec
  • +
  • 1M writes/sec (during lean hours)
  • +
+

All of this ran on Cassandra. While its distributed architecture had been proven in production, operating large-scale clusters came with considerable infrastructure overhead. Our proof-of-concept (POC) demonstrated throughput of around 100K ops/sec, but as we scaled further, the challenges grew. Ensuring node health, optimizing compaction, and maintaining storage balance became increasingly demanding. We also observed latency spikes under heavy load, alongside a sharp increase in total cost of ownership.

+

Interaction Store Woes

+

Our interaction store was another ticking time bomb:

+
    +
  • 🚨 Clusters kept growing in size and cost
  • +
  • 🚨 Latency spikes became increasingly frequent
  • +
  • 🚨 The DMC proxy occasionally lost locality of nodes against shards, causing cross-node communication and degraded performance
  • +
+

Each time this happened, we had to manually rebalance shards just to restore stable latency, making operations unsustainable at scale.

+

Silver Linings

+

Despite the chaos, the system was live and delivering value:

+
    +
  • Real-time infrastructure was in production
  • +
  • Costs dropped by 60–70% compared to offline personalization
  • +
  • New experiments rolled out faster and more successfully
  • +
  • User engagement metrics improved
  • +
+

It wasn’t perfect. It was far from easy. But it worked—and that counted for a lot.

+

Round Two: Solving the Top 2 Bottlenecks

+

With the first-gen system stretched to its limits, we stepped back. Conversations with data scientists and backend engineers revealed three recurring pain points:

+
    +
  1. Coding feature retrieval logic for every new model was becoming unsustainable
  2. +
  3. ML scale was exploding—bringing rising infra costs with it
  4. +
  5. Real-time embedding search was the next big unlock
  6. +
+

We tackled them one by one—starting with the biggest pain point.

+

Problem 1: No-Code Feature Retrieval for Model Inference

+

We noticed a pattern: for personalized ranking, models needed features from:

+
    +
  • ✅ Product
  • +
  • ✅ User
  • +
  • ✅ User × Category
  • +
  • ✅ Region, cohort, sub-category, etc.
  • +
+

A key insight emerged: Entities that contribute features for a model always map back to the context entities.

+

MP Dag

+

With this, we designed Inferflow, a graph-driven feature retrieval and model orchestration system:

+
    +
  • 1️⃣ Inferflow takes a modelId and context IDs (e.g., userId, productIds)
  • +
  • 2️⃣ Loads a pre-defined feature retrieval graph from ZooKeeper
  • +
  • 3️⃣ Executes the graph to resolve entity relationships dynamically
  • +
  • 4️⃣ Outputs a 2D matrix of feature vectors
  • +
+

💡 The impact?

+
    +
  • 🚀 No more custom feature retrieval code—just graph updates in config
  • +
  • 🚀 Feature consistency across experiments
  • +
  • 🚀 Faster iteration cycles for ranking, fraud detection, and beyond
  • +
+

Here’s a visual example that shows how this graph plays out during execution. We further extended the graph to call multiple models as needed: +MP matrix +We built Inferflow in GoLang, using gRPC and Proto3 serialization for efficiency.

+

Problem 2: Scaling Without Breaking the Bank

+

With more ML use cases coming online, we needed to cut costs without compromising performance. We focused on:

+
    +
  • 🔹 Online Feature Store
  • +
  • 🔹 Interaction Store
  • +
+

Optimizing the Online Feature Store

+

Our costs were concentrated in:

+
    +
  • 📌 Database (Cassandra)
  • +
  • 📌 Cache (Redis)
  • +
  • 📌 Running Pods (Java services)
  • +
+

1️⃣ Replacing Cassandra with ScyllaDB +As we hit the operational limits of large Cassandra clusters, we transitioned to ScyllaDB, which offered a seamless drop-in replacement without major code changes. The switch brought significant benefits:

+
    +
  • Throughput: Matched or exceeded Cassandra's performance under identical workloads, even under high concurrency.
  • +
  • Latency: Achieved consistently lower P99 latencies due to ScyllaDB's shard-per-core architecture and better I/O utilization.
  • +
  • Cost Efficiency: Reduced infra footprint by ~70% through better CPU and memory efficiency, eliminating the need for over-provisioned nodes.
  • +
+

2️⃣ Finding the Right Cache +To reduce backend load and improve response times, we benchmarked multiple caching solutions—Memcached, KeyDB, and Dragonfly—under real production traffic patterns. Dragonfly stood out due to its robust architecture and operational simplicity:

+
    +
  • Data Skew Handling: Efficiently managed extreme key hotness and uneven access patterns without performance degradation.
  • +
  • Throughput: Delivered consistently high throughput, even with large object sizes and concurrent access.
  • +
  • Ease of Adoption: Acted as a drop-in Redis replacement with full protocol compatibility—no changes needed in application code or client libraries.
  • +
+

3️⃣ Moving to GoLang for Cost-Efficient Serving +Java services were memory-heavy—so we rewrote core services in GoLang. The results?

+

✅ Memory usage dropped by ~80% +✅ CPU utilization was significantly lower +✅ Faster, more efficient deployments

+

Optimizing the Interaction Store

+

We realized that we only need a user’s interaction data in Redis when they open the app. So, we implemented a tiered storage approach:

+
    +
  • 📌 Cold Tier (ScyllaDB)—Stores click, order, wishlist events
  • +
  • 📌 Hot Tier (Redis)—Loads a user’s past interactions only when they open the app
  • +
+

Smart Offloading: We introduced an inactivity tracker to detect when a user session ends. At that point, Redis data was flushed back to Scylla, reducing unnecessary writes.

+

InteractionStore

+

Results

+
    +
  • Online Feature Store hit 1M QPS for the first time during the 2023 Mega Blockbuster Sale—without breaking a sweat
  • +
  • Infra costs for Online Feature Store and Interaction Store dropped by ~60%
  • +
+

The Catch: Our ML Hosting Hit a Hard Limit

+

While planning for 2023 MBS, we ran into a critical scalability bottleneck:

+
    +
  • ❌ Insufficient compute availability in our region for ML instances
  • +
  • ❌ Couldn’t provision enough nodes to handle real-time inference at scale
  • +
+

This forced us to rethink where and how we hosted our models. The existing setup was great for prototyping—but it wasn’t built to handle the bursty, high-QPS demands of real-world production workloads.

+

Conclusion: From Firefighting to Future-Proofing

+

What started as an ambitious experiment turned into a real-time ML infrastructure that powered millions of requests per second. We battled scaling pains, rethought feature retrieval with Inferflow, and rebuilt our infra stack for efficiency—driving down costs while improving experimentation velocity. +But new challenges emerged. Our infrastructure could now handle scale, but our ML model hosting setup hit a hard limit. With compute availability bottlenecks threatening real-time inference, we faced a critical decision: how do we make model serving as scalable and cost-efficient as the rest of our stack? That’s the next piece of the puzzle—and the story of Part 3.

]]>
+ inferflow + interaction-store + mlplatform + meesho + bharatmlstack +
<![CDATA[Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1)]]> https://meesho.github.io/BharatMLStack/blog/post-one https://meesho.github.io/BharatMLStack/blog/post-one Tue, 15 Nov 2022 00:00:00 GMT - BharatMLStack

+ BharatMLStack

The Genesis: How a Friday Night Roast Sparked Meesho’s ML Platform

It all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting—until one remark hit a little too close to home:

"Why are we still crunching data for Monthly Active Users (MAU) when the next day it’s all about Daily Active Users (DAU)?"

diff --git a/docs/blog/tags/bharatmlstack/index.html b/docs/blog/tags/bharatmlstack/index.html new file mode 100644 index 00000000..9bf61277 --- /dev/null +++ b/docs/blog/tags/bharatmlstack/index.html @@ -0,0 +1,360 @@ + + + + + +4 posts tagged with "bharatmlstack" | BharatMLStack + + + + + + + + +

4 posts tagged with "bharatmlstack"

View All Tags

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

· 5 min read
Jaya Kumar
Lead ML Engineer @ Meesho

BharatMLStack

+

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

+

Raw execution of Large Language Models is inherently expensive and memory-intensive. To achieve sub-second latency and high throughput, we implement a multi-layered optimization strategy that targets the entire inference stack—from memory management to kernel execution.

+

1. Advanced Memory Management: Paged & Prefix KV Caching

+

The most significant bottleneck in LLM inference is not always compute, but memory bandwidth—specifically managing the Key-Value (KV) cache.

+

Paged KV caching

+

Standard caching suffers from fragmentation. We use Paged KV caching, which operates similarly to an operating system's virtual memory: the KV cache is divided into non-contiguous blocks. This lets us serve larger batch sizes without running out of memory.

+

KV cache quantization

+

To further maximize available memory, we implement KV cache quantization (e.g., FP8). By compressing stored attention keys and values from 16-bit to 8-bit, we nearly double the effective context window capacity of the GPU, allowing longer conversations or larger batches without materially degrading quality.

+

Prefix caching (the "voice bot" optimizer)

+

For use cases like GenAI voice bots where the system prompt (e.g., "You are a helpful assistant...") is static across thousands of requests, we enable prefix caching.

+
    +
  • Impact: By reusing pre-computed KV states for common prefixes, we achieve a cache hit rate of ~90%. This reduces Time To First Token (TTFT) by skipping redundant computation of the system prompt.
  • +
+

2. Aggressive Quantization (INT4 AWQ & FP8)

+

Running models in their native 16-bit precision (BF16) restricts maximum batch size and throughput. We use quantization to shrink model weights without sacrificing accuracy.

+

INT4 AWQ (Activation-aware Weight Quantization)

+

For the Llama 3 family, we use AWQ to compress weights to 4 bits. This reduces model size by ~75%, allowing larger models to fit into L4 GPU memory and significantly improving token generation speed.

+

FP8 precision

+

For NVIDIA Hopper (H100) architectures, we are exploring FP8 quantization, leveraging native FP8 tensor cores to accelerate matrix multiplications while maintaining a higher dynamic range than integer quantization.

+
    +
  • Verification: We validate quantized models by comparing dot-product similarity of embeddings against the FP16 baseline, consistently achieving >99% similarity.
  • +
+

3. Kernel Fusion & Custom Plugins

+

To minimize overhead from launching thousands of small GPU operations, we fuse them into monolithic kernels using NVIDIA TensorRT plugins.

+
    +
  • Flash attention & FMHA: We enable Fused Multi-Head Attention (FMHA) combined with flash attention to reduce memory reads/writes.
  • +
  • GEMM plugins: We use specialized GEMM plugins to accelerate transformer linear layers.
  • +
  • Removing input padding: Instead of padding short sequences to match the longest, we remove input padding so the GPU processes only valid tokens.
  • +
+

4. Inflight (Continuous) Batching

+

Traditional static batching waits for all requests in a batch to finish before returning results—so one long response delays everyone else.

+

We implement inflight batching: as soon as one request completes, its slot is freed and filled by a new request from the queue. This keeps GPUs saturated and decouples latency of short queries from long ones.

+

5. Parallelism Strategies: Scaling Beyond One GPU

+

For large models (e.g., 70B+ parameters) that cannot fit into the VRAM of a single GPU, we use parallelism strategies.

+
    +
  • Tensor parallelism (TP): Split weight matrices across multiple GPUs (e.g., 4× L4 or 8× A100). Each GPU computes a shard and outputs are reduced at every layer.
  • +
  • Pipeline parallelism (PP): Split model layers across GPUs to pipeline compute (e.g., while one GPU computes later layers for Request A, another starts early layers for Request B).
  • +
+

6. Speculative Decoding

+

To reduce inter-token latency (ITL), we explore speculative decoding.

+
    +
  • Mechanism: A smaller, faster "draft" model speculatively generates a short token sequence (e.g., 5 tokens).
  • +
  • Verification: The larger target model verifies those tokens in one parallel forward pass. If correct, we effectively generate multiple tokens per large-model step; if not, we discard and regenerate. This is effective for predictable text, improving perceived generation speed.
  • +
+

Few Benchmarks

+

Below are a couple of representative use cases and performance numbers.

+

Search query rewriting

+
    +
  • LLM: Fine-tuned llama-3.2-1B
  • +
  • Input & output token length: ~10–20
  • +
  • Response type: Non-streaming
  • +
+
Inference runtimeHardwareMax requests/secMax p99 latency
TensorRT-LLM4 × L4 GPUs (multi-GPU)100095 ms
TensorRT-LLM1 × A100 40 GB GPU100069 ms
+

Voice bot query

+
    +
  • LLM: Llama-3.1-8B
  • +
  • Input token length: ~1900–2000
  • +
  • Output token length: ~200
  • +
  • Response type: Streaming
  • +
+
Inference runtimeConcurrencyp99 TTFT (ms)p99 ITL (ms)Token throughput (tokens/sec)Request throughput (req/sec)Hardware
TensorRT-LLM136.2722.7845.660.23L4
TensorRT-LLM249.8123.2189.370.45L4
TensorRT-LLM455.3336.62153.390.78L4
TensorRT-LLM866.539.11279.881.47L4
TensorRT-LLM16131.830.39547.82.77L4
TensorRT-LLM32277.2248.02925.74.78L4
TensorRT-LLM64498.5271.621,164.406.2L4
TensorRT-LLM128677.31120.371,445.187.69L4
TensorRT-LLM2561,926.31216.881,600.818.52L4
TensorRT-LLM121.179.24130.050.68A100
TensorRT-LLM225.789.21264.51.35A100
TensorRT-LLM428.5210.99437.692.27A100
TensorRT-LLM834.412.61760.493.96A100
TensorRT-LLM1668.0314.321,343.807.01A100
TensorRT-LLM32185.9616.822,287.3011.92A100
TensorRT-LLM64136.8721.173,625.2218.89A100
TensorRT-LLM128463.7834.154,456.5123.24A100
TensorRT-LLM256890.1259.185,188.2427.05A100
+

Conclusion

+

High-performance LLM inference is fundamentally a systems engineering problem: memory efficiency, kernel execution, batching strategy, and parallelism determine real-world latency and throughput. Techniques such as paged KV caching, aggressive quantization, kernel fusion, and inflight batching improve GPU utilization while reducing latency and memory pressure.

+

These optimizations enable the platform to deliver sub-second responses, sustain high concurrency, and efficiently serve both lightweight and long-context workloads. By continuously optimizing across the full inference stack, we keep LLM serving scalable, cost-efficient, and production-ready for real-time AI applications.

Cracking the Code: Scaling Model Inference & Real-Time Embedding Search

· 4 min read
Aditya Kumar
Lead Software Engineer @ Meesho
Jaya Kumar
Lead ML Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+ +

By mid-2023, we had transformed our ML stack—building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:

+
    +
  • 🔹 Scaling model inference without hitting infrastructure roadblocks
  • +
  • 🔹 Moving embedding search from batch to real-time for candidate generation
  • +
+

Here’s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system.

+

Breaking Free from the Scalability Ceiling

+

The Model Serving Bottleneck—A Wake-Up Call

+

July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue—scaling our model-serving infrastructure was taking 10–15 minutes. In real-time ML, that’s an eternity. +In one of our war rooms, we ran a quick experiment:

+
    +
  • 🚀 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine.
  • +
  • 🚀 Fired requests and compared the outputs with our existing cloud-hosted setup.
  • +
  • 🚀 The results matched—perfectly.
  • +
+

That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn't allocate enough compute resources in time. Luckily, they did—but the seed was planted. +Then in October, just two weeks before MBS, we got an alarming response from our infrastructure team: +"Node availability may be an issue." +With no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?

+
    +
  • ✅ p99 latency dropped from 90–100ms to 30–40ms
  • +
  • ✅ Triton handled significantly higher throughput on fewer resources
  • +
  • ✅ No model changes were needed
  • +
+

MBS ran without a hitch, proving that self-hosted inference was the way forward.

+

Scaling Triton on GKE

+

This left us with two choices:

+
    +
  • 1️⃣ Port models to a managed cloud inference service, investing time in learning a new deployment stack
  • +
  • 2️⃣ Scale our existing Triton setup on GKE, optimizing for cost and performance
  • +
+

We went with Option 2—and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations.

+

Fixing the Cold Start Problem

+

As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7–9 minutes to spin up.

+

After profiling, we found the culprits:

+
    +
  • Triton’s base image—a massive 5GB
  • +
  • Model binaries—often 1GB+
  • +
  • Startup delay—mostly due to downloading and initializing these assets
  • +
+

To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother.

+

Embedding Search: The Last Piece of the Puzzle

+

By mid-2023, most of our ML stack had gone real-time—except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system.

+

Choosing the Right Vector Database

+

We benchmarked three production-ready vector DBs across key parameters:

+
    +
  • Milvus
  • +
  • Qdrant
  • +
  • Weaviate
  • +
+

After extensive POCs, Qdrant stood out for its:

+
    +
  • ✅ Blazing-fast search latency on high-dimensional vectors
  • +
  • ✅ Efficient memory usage, crucial for in-memory workloads
  • +
  • ✅ Support for upserts and soft deletes, vital for Ads use cases
  • +
  • ✅ gRPC + REST APIs, making integration seamless
  • +
  • ✅ Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)
  • +
+

At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search—a perfect fit for our needs.

+

Embedding Freshness & Real-Time Updates

+

To ensure embeddings stayed up to date, we built a dual ingestion pipeline:

+
    +
  • 📌 Daily Refresh: A bulk pipeline updated embeddings overnight
  • +
  • 📌 Real-Time Updates: Ads events triggered immediate upserts/deletes
  • +
+

This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.

+

Skye

+

Final Takeaways: Scaling Smartly for Real-Time ML

+
    +
  • 🚀 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services
  • +
  • 🚀 Building a custom Triton image reduced cold starts, improving responsiveness
  • +
  • 🚀 Qdrant-based embedding search enabled real-time personalization at scale
  • +
  • 🚀 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations
  • +
+

By early 2024, Meesho’s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead.

Cracking the Code: Scaling Model Inference & Real-Time Embedding Search

· 4 min read
Aditya Kumar
Lead Software Engineer @ Meesho
Jaya Kumar
Lead ML Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+ +

By mid-2023, we had transformed our ML stack—building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:

+
    +
  • 🔹 Scaling model inference without hitting infrastructure roadblocks
  • +
  • 🔹 Moving embedding search from batch to real-time for candidate generation
  • +
+

Here’s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system.

+

Breaking Free from the Scalability Ceiling

+

The Model Serving Bottleneck—A Wake-Up Call

+

July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue—scaling our model-serving infrastructure was taking 10–15 minutes. In real-time ML, that’s an eternity. +In one of our war rooms, we ran a quick experiment:

+
    +
  • 🚀 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine.
  • +
  • 🚀 Fired requests and compared the outputs with our existing cloud-hosted setup.
  • +
  • 🚀 The results matched—perfectly.
  • +
+

That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn't allocate enough compute resources in time. Luckily, they did—but the seed was planted. +Then in October, just two weeks before MBS, we got an alarming response from our infrastructure team: +"Node availability may be an issue." +With no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?

+
    +
  • ✅ p99 latency dropped from 90–100ms to 30–40ms
  • +
  • ✅ Triton handled significantly higher throughput on fewer resources
  • +
  • ✅ No model changes were needed
  • +
+

MBS ran without a hitch, proving that self-hosted inference was the way forward.

+

Scaling Triton on GKE

+

This left us with two choices:

+
    +
  • 1️⃣ Port models to a managed cloud inference service, investing time in learning a new deployment stack
  • +
  • 2️⃣ Scale our existing Triton setup on GKE, optimizing for cost and performance
  • +
+

We went with Option 2—and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations.

+

Fixing the Cold Start Problem

+

As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7–9 minutes to spin up.

+

After profiling, we found the culprits:

+
    +
  • Triton’s base image—a massive 5GB
  • +
  • Model binaries—often 1GB+
  • +
  • Startup delay—mostly due to downloading and initializing these assets
  • +
+

To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother.

+

Embedding Search: The Last Piece of the Puzzle

+

By mid-2023, most of our ML stack had gone real-time—except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system.

+

Choosing the Right Vector Database

+

We benchmarked three production-ready vector DBs across key parameters:

+
    +
  • Milvus
  • +
  • Qdrant
  • +
  • Weaviate
  • +
+

After extensive POCs, Qdrant stood out for its:

+
    +
  • ✅ Blazing-fast search latency on high-dimensional vectors
  • +
  • ✅ Efficient memory usage, crucial for in-memory workloads
  • +
  • ✅ Support for upserts and soft deletes, vital for Ads use cases
  • +
  • ✅ gRPC + REST APIs, making integration seamless
  • +
  • ✅ Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)
  • +
+

At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search—a perfect fit for our needs.

+

Embedding Freshness & Real-Time Updates

+

To ensure embeddings stayed up to date, we built a dual ingestion pipeline:

+
    +
  • 📌 Daily Refresh: A bulk pipeline updated embeddings overnight
  • +
  • 📌 Real-Time Updates: Ads events triggered immediate upserts/deletes
  • +
+

This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.

+

Skye

+

Final Takeaways: Scaling Smartly for Real-Time ML

+
    +
  • 🚀 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services
  • +
  • 🚀 Building a custom Triton image reduced cold starts, improving responsiveness
  • +
  • 🚀 Qdrant-based embedding search enabled real-time personalization at scale
  • +
  • 🚀 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations
  • +
+

By early 2024, Meesho’s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead.

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

· 7 min read
Bhawani Singh
Architect @ Meesho
Jigar Dave
Lead Software Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

+

By late 2022, we had built something we were truly proud of—a real-time ML serving system with a DAG-based executor, a feature store, and an interaction store powering key ranking and personalization models. It was a major milestone, the culmination of months of effort from data scientists, ML engineers, and backend teams. Our system was live, and we were ready to push the boundaries of experimentation. +And it worked. Mostly. +But soon, cracks appeared. Every new model needed custom feature retrieval logic, DAGs became dense and unmanageable, and scaling turned into a constant firefight. Costs surged, and infra bottlenecks slowed experimentation. Our system worked, but it wasn’t built for scale. +This is the story of how we tackled these challenges—building Inferflow for seamless feature retrieval, optimizing real-time infra, and cutting costs while scaling to millions of QPS.

+

The Cost of Success

+

Every new Ranker model required its own feature set, often pulling from different entities. Each addition meant:

+
    +
  • Adding new DAG nodes in IOP
  • +
  • Writing custom logic to fetch features from multiple sources (e.g., user, product, user × category)
  • +
  • Inferring intermediate features (e.g., extracting category from a product to fetch user × category data)
  • +
  • Optimizing I/O and dealing with the inevitable bugs
  • +
+

What began as clean DAGs soon turned into a tangled web of cross-dependent graphs. Every experimentation cycle meant new nodes, new dependencies, and slower iterations.

+

Scaling Pains (and Cassandra’s Limits)

+

At some point, we were hitting:

+
    +
  • 250–300K reads/sec
  • +
  • 1M writes/sec (during lean hours)
  • +
+

All of this ran on Cassandra. While its distributed architecture had been proven in production, operating large-scale clusters came with considerable infrastructure overhead. Our proof-of-concept (POC) demonstrated throughput of around 100K ops/sec, but as we scaled further, the challenges grew. Ensuring node health, optimizing compaction, and maintaining storage balance became increasingly demanding. We also observed latency spikes under heavy load, alongside a sharp increase in total cost of ownership.

+

Interaction Store Woes

+

Our interaction store was another ticking time bomb:

+
    +
  • 🚨 Clusters kept growing in size and cost
  • +
  • 🚨 Latency spikes became increasingly frequent
  • +
  • 🚨 The DMC proxy occasionally lost locality of nodes against shards, causing cross-node communication and degraded performance
  • +
+

Each time this happened, we had to manually rebalance shards just to restore stable latency, making operations unsustainable at scale.

+

Silver Linings

+

Despite the chaos, the system was live and delivering value:

+
    +
  • Real-time infrastructure was in production
  • +
  • Costs dropped by 60–70% compared to offline personalization
  • +
  • New experiments rolled out faster and more successfully
  • +
  • User engagement metrics improved
  • +
+

It wasn’t perfect. It was far from easy. But it worked—and that counted for a lot.

+

Round Two: Solving the Top 2 Bottlenecks

+

With the first-gen system stretched to its limits, we stepped back. Conversations with data scientists and backend engineers revealed three recurring pain points:

+
    +
  1. Coding feature retrieval logic for every new model was becoming unsustainable
  2. +
  3. ML scale was exploding—bringing rising infra costs with it
  4. +
  5. Real-time embedding search was the next big unlock
  6. +
+

We tackled them one by one—starting with the biggest pain point.

+

Problem 1: No-Code Feature Retrieval for Model Inference

+

We noticed a pattern: for personalized ranking, models needed features from:

+
    +
  • ✅ Product
  • +
  • ✅ User
  • +
  • ✅ User × Category
  • +
  • ✅ Region, cohort, sub-category, etc.
  • +
+

A key insight emerged: Entities that contribute features for a model always map back to the context entities.

+

MP Dag

+

With this, we designed Inferflow, a graph-driven feature retrieval and model orchestration system:

+
    +
  • 1️⃣ Inferflow takes a modelId and context IDs (e.g., userId, productIds)
  • +
  • 2️⃣ Loads a pre-defined feature retrieval graph from ZooKeeper
  • +
  • 3️⃣ Executes the graph to resolve entity relationships dynamically
  • +
  • 4️⃣ Outputs a 2D matrix of feature vectors
  • +
+

💡 The impact?

+
    +
  • 🚀 No more custom feature retrieval code—just graph updates in config
  • +
  • 🚀 Feature consistency across experiments
  • +
  • 🚀 Faster iteration cycles for ranking, fraud detection, and beyond
  • +
+

Here’s a visual example that shows how this graph plays out during execution. We further extended the graph to call multiple models as needed: +MP matrix +We built Inferflow in GoLang, using gRPC and Proto3 serialization for efficiency.

+

Problem 2: Scaling Without Breaking the Bank

+

With more ML use cases coming online, we needed to cut costs without compromising performance. We focused on:

+
    +
  • 🔹 Online Feature Store
  • +
  • 🔹 Interaction Store
  • +
+

Optimizing the Online Feature Store

+

Our costs were concentrated in:

+
    +
  • 📌 Database (Cassandra)
  • +
  • 📌 Cache (Redis)
  • +
  • 📌 Running Pods (Java services)
  • +
+

1️⃣ Replacing Cassandra with ScyllaDB +As we hit the operational limits of large Cassandra clusters, we transitioned to ScyllaDB, which offered a seamless drop-in replacement without major code changes. The switch brought significant benefits:

+
    +
  • Throughput: Matched or exceeded Cassandra's performance under identical workloads, even under high concurrency.
  • +
  • Latency: Achieved consistently lower P99 latencies due to ScyllaDB's shard-per-core architecture and better I/O utilization.
  • +
  • Cost Efficiency: Reduced infra footprint by ~70% through better CPU and memory efficiency, eliminating the need for over-provisioned nodes.
  • +
+

2️⃣ Finding the Right Cache +To reduce backend load and improve response times, we benchmarked multiple caching solutions—Memcached, KeyDB, and Dragonfly—under real production traffic patterns. Dragonfly stood out due to its robust architecture and operational simplicity:

+
    +
  • Data Skew Handling: Efficiently managed extreme key hotness and uneven access patterns without performance degradation.
  • +
  • Throughput: Delivered consistently high throughput, even with large object sizes and concurrent access.
  • +
  • Ease of Adoption: Acted as a drop-in Redis replacement with full protocol compatibility—no changes needed in application code or client libraries.
  • +
+

3️⃣ Moving to GoLang for Cost-Efficient Serving +Java services were memory-heavy—so we rewrote core services in GoLang. The results?

+

✅ Memory usage dropped by ~80% +✅ CPU utilization was significantly lower +✅ Faster, more efficient deployments

+

Optimizing the Interaction Store

+

We realized that we only need a user’s interaction data in Redis when they open the app. So, we implemented a tiered storage approach:

+
    +
  • 📌 Cold Tier (ScyllaDB)—Stores click, order, wishlist events
  • +
  • 📌 Hot Tier (Redis)—Loads a user’s past interactions only when they open the app
  • +
+

Smart Offloading: We introduced an inactivity tracker to detect when a user session ends. At that point, Redis data was flushed back to Scylla, reducing unnecessary writes.

+

InteractionStore

+

Results

+
    +
  • Online Feature Store hit 1M QPS for the first time during the 2023 Mega Blockbuster Sale—without breaking a sweat
  • +
  • Infra costs for Online Feature Store and Interaction Store dropped by ~60%
  • +
+

The Catch: Our ML Hosting Hit a Hard Limit

+

While planning for 2023 MBS, we ran into a critical scalability bottleneck:

+
    +
  • ❌ Insufficient compute availability in our region for ML instances
  • +
  • ❌ Couldn’t provision enough nodes to handle real-time inference at scale
  • +
+

This forced us to rethink where and how we hosted our models. The existing setup was great for prototyping—but it wasn’t built to handle the bursty, high-QPS demands of real-world production workloads.

+

Conclusion: From Firefighting to Future-Proofing

+

What started as an ambitious experiment turned into a real-time ML infrastructure that powered millions of requests per second. We battled scaling pains, rethought feature retrieval with Inferflow, and rebuilt our infra stack for efficiency—driving down costs while improving experimentation velocity. +But new challenges emerged. Our infrastructure could now handle scale, but our ML model hosting setup hit a hard limit. With compute availability bottlenecks threatening real-time inference, we faced a critical decision: how do we make model serving as scalable and cost-efficient as the rest of our stack? That’s the next piece of the puzzle—and the story of Part 3.

+ + \ No newline at end of file diff --git a/docs/blog/tags/embedding-search/index.html b/docs/blog/tags/embedding-search/index.html new file mode 100644 index 00000000..33570fb8 --- /dev/null +++ b/docs/blog/tags/embedding-search/index.html @@ -0,0 +1,93 @@ + + + + + +One post tagged with "embedding-search" | BharatMLStack + + + + + + + + +

One post tagged with "embedding-search"

View All Tags

Cracking the Code: Scaling Model Inference & Real-Time Embedding Search

· 4 min read
Aditya Kumar
Lead Software Engineer @ Meesho
Jaya Kumar
Lead ML Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+ +

By mid-2023, we had transformed our ML stack—building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:

+
    +
  • 🔹 Scaling model inference without hitting infrastructure roadblocks
  • +
  • 🔹 Moving embedding search from batch to real-time for candidate generation
  • +
+

Here’s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system.

+

Breaking Free from the Scalability Ceiling

+

The Model Serving Bottleneck—A Wake-Up Call

+

July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue—scaling our model-serving infrastructure was taking 10–15 minutes. In real-time ML, that’s an eternity. +In one of our war rooms, we ran a quick experiment:

+
    +
  • 🚀 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine.
  • +
  • 🚀 Fired requests and compared the outputs with our existing cloud-hosted setup.
  • +
  • 🚀 The results matched—perfectly.
  • +
+

That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn't allocate enough compute resources in time. Luckily, they did—but the seed was planted. +Then in October, just two weeks before MBS, we got an alarming response from our infrastructure team: +"Node availability may be an issue." +With no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?

+
    +
  • ✅ p99 latency dropped from 90–100ms to 30–40ms
  • +
  • ✅ Triton handled significantly higher throughput on fewer resources
  • +
  • ✅ No model changes were needed
  • +
+

MBS ran without a hitch, proving that self-hosted inference was the way forward.

+

Scaling Triton on GKE

+

This left us with two choices:

+
    +
  • 1️⃣ Port models to a managed cloud inference service, investing time in learning a new deployment stack
  • +
  • 2️⃣ Scale our existing Triton setup on GKE, optimizing for cost and performance
  • +
+

We went with Option 2—and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations.

+

Fixing the Cold Start Problem

+

As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7–9 minutes to spin up.

+

After profiling, we found the culprits:

+
    +
  • Triton’s base image—a massive 5GB
  • +
  • Model binaries—often 1GB+
  • +
  • Startup delay—mostly due to downloading and initializing these assets
  • +
+

To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother.

+

Embedding Search: The Last Piece of the Puzzle

+

By mid-2023, most of our ML stack had gone real-time—except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system.

+

Choosing the Right Vector Database

+

We benchmarked three production-ready vector DBs across key parameters:

+
    +
  • Milvus
  • +
  • Qdrant
  • +
  • Weaviate
  • +
+

After extensive POCs, Qdrant stood out for its:

+
    +
  • ✅ Blazing-fast search latency on high-dimensional vectors
  • +
  • ✅ Efficient memory usage, crucial for in-memory workloads
  • +
  • ✅ Support for upserts and soft deletes, vital for Ads use cases
  • +
  • ✅ gRPC + REST APIs, making integration seamless
  • +
  • ✅ Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)
  • +
+

At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search—a perfect fit for our needs.

+

Embedding Freshness & Real-Time Updates

+

To ensure embeddings stayed up to date, we built a dual ingestion pipeline:

+
    +
  • 📌 Daily Refresh: A bulk pipeline updated embeddings overnight
  • +
  • 📌 Real-Time Updates: Ads events triggered immediate upserts/deletes
  • +
+

This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.

+

Skye

+

Final Takeaways: Scaling Smartly for Real-Time ML

+
    +
  • 🚀 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services
  • +
  • 🚀 Building a custom Triton image reduced cold starts, improving responsiveness
  • +
  • 🚀 Qdrant-based embedding search enabled real-time personalization at scale
  • +
  • 🚀 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations
  • +
+

By early 2024, Meesho’s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead.

+ + \ No newline at end of file diff --git a/docs/blog/tags/index.html b/docs/blog/tags/index.html index 01854bc7..c5d991bf 100644 --- a/docs/blog/tags/index.html +++ b/docs/blog/tags/index.html @@ -4,14 +4,14 @@ Tags | BharatMLStack - - - + + + - + \ No newline at end of file diff --git a/docs/blog/tags/inferflow/index.html b/docs/blog/tags/inferflow/index.html new file mode 100644 index 00000000..78e772c0 --- /dev/null +++ b/docs/blog/tags/inferflow/index.html @@ -0,0 +1,144 @@ + + + + + +One post tagged with "inferflow" | BharatMLStack + + + + + + + + +

One post tagged with "inferflow"

View All Tags

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

· 7 min read
Bhawani Singh
Architect @ Meesho
Jigar Dave
Lead Software Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

+

By late 2022, we had built something we were truly proud of—a real-time ML serving system with a DAG-based executor, a feature store, and an interaction store powering key ranking and personalization models. It was a major milestone, the culmination of months of effort from data scientists, ML engineers, and backend teams. Our system was live, and we were ready to push the boundaries of experimentation. +And it worked. Mostly. +But soon, cracks appeared. Every new model needed custom feature retrieval logic, DAGs became dense and unmanageable, and scaling turned into a constant firefight. Costs surged, and infra bottlenecks slowed experimentation. Our system worked, but it wasn’t built for scale. +This is the story of how we tackled these challenges—building Inferflow for seamless feature retrieval, optimizing real-time infra, and cutting costs while scaling to millions of QPS.

+

The Cost of Success

+

Every new Ranker model required its own feature set, often pulling from different entities. Each addition meant:

+
    +
  • Adding new DAG nodes in IOP
  • +
  • Writing custom logic to fetch features from multiple sources (e.g., user, product, user × category)
  • +
  • Inferring intermediate features (e.g., extracting category from a product to fetch user × category data)
  • +
  • Optimizing I/O and dealing with the inevitable bugs
  • +
+

What began as clean DAGs soon turned into a tangled web of cross-dependent graphs. Every experimentation cycle meant new nodes, new dependencies, and slower iterations.

+

Scaling Pains (and Cassandra’s Limits)

+

At some point, we were hitting:

+
    +
  • 250–300K reads/sec
  • +
  • 1M writes/sec (during lean hours)
  • +
+

All of this ran on Cassandra. While its distributed architecture had been proven in production, operating large-scale clusters came with considerable infrastructure overhead. Our proof-of-concept (POC) demonstrated throughput of around 100K ops/sec, but as we scaled further, the challenges grew. Ensuring node health, optimizing compaction, and maintaining storage balance became increasingly demanding. We also observed latency spikes under heavy load, alongside a sharp increase in total cost of ownership.

+

Interaction Store Woes

+

Our interaction store was another ticking time bomb:

+
    +
  • 🚨 Clusters kept growing in size and cost
  • +
  • 🚨 Latency spikes became increasingly frequent
  • +
  • 🚨 The DMC proxy occasionally lost locality of nodes against shards, causing cross-node communication and degraded performance
  • +
+

Each time this happened, we had to manually rebalance shards just to restore stable latency, making operations unsustainable at scale.

+

Silver Linings

+

Despite the chaos, the system was live and delivering value:

+
    +
  • Real-time infrastructure was in production
  • +
  • Costs dropped by 60–70% compared to offline personalization
  • +
  • New experiments rolled out faster and more successfully
  • +
  • User engagement metrics improved
  • +
+

It wasn’t perfect. It was far from easy. But it worked—and that counted for a lot.

+

Round Two: Solving the Top 2 Bottlenecks

+

With the first-gen system stretched to its limits, we stepped back. Conversations with data scientists and backend engineers revealed three recurring pain points:

+
    +
  1. Coding feature retrieval logic for every new model was becoming unsustainable
  2. +
  3. ML scale was exploding—bringing rising infra costs with it
  4. +
  5. Real-time embedding search was the next big unlock
  6. +
+

We tackled them one by one—starting with the biggest pain point.

+

Problem 1: No-Code Feature Retrieval for Model Inference

+

We noticed a pattern: for personalized ranking, models needed features from:

+
    +
  • ✅ Product
  • +
  • ✅ User
  • +
  • ✅ User × Category
  • +
  • ✅ Region, cohort, sub-category, etc.
  • +
+

A key insight emerged: Entities that contribute features for a model always map back to the context entities.

+

MP Dag

+

With this, we designed Inferflow, a graph-driven feature retrieval and model orchestration system:

+
    +
  • 1️⃣ Inferflow takes a modelId and context IDs (e.g., userId, productIds)
  • +
  • 2️⃣ Loads a pre-defined feature retrieval graph from ZooKeeper
  • +
  • 3️⃣ Executes the graph to resolve entity relationships dynamically
  • +
  • 4️⃣ Outputs a 2D matrix of feature vectors
  • +
+

💡 The impact?

+
    +
  • 🚀 No more custom feature retrieval code—just graph updates in config
  • +
  • 🚀 Feature consistency across experiments
  • +
  • 🚀 Faster iteration cycles for ranking, fraud detection, and beyond
  • +
+

Here’s a visual example that shows how this graph plays out during execution. We further extended the graph to call multiple models as needed: +MP matrix +We built Inferflow in GoLang, using gRPC and Proto3 serialization for efficiency.

+

Problem 2: Scaling Without Breaking the Bank

+

With more ML use cases coming online, we needed to cut costs without compromising performance. We focused on:

+
    +
  • 🔹 Online Feature Store
  • +
  • 🔹 Interaction Store
  • +
+

Optimizing the Online Feature Store

+

Our costs were concentrated in:

+
    +
  • 📌 Database (Cassandra)
  • +
  • 📌 Cache (Redis)
  • +
  • 📌 Running Pods (Java services)
  • +
+

1️⃣ Replacing Cassandra with ScyllaDB +As we hit the operational limits of large Cassandra clusters, we transitioned to ScyllaDB, which offered a seamless drop-in replacement without major code changes. The switch brought significant benefits:

+
    +
  • Throughput: Matched or exceeded Cassandra's performance under identical workloads, even under high concurrency.
  • +
  • Latency: Achieved consistently lower P99 latencies due to ScyllaDB's shard-per-core architecture and better I/O utilization.
  • +
  • Cost Efficiency: Reduced infra footprint by ~70% through better CPU and memory efficiency, eliminating the need for over-provisioned nodes.
  • +
+

2️⃣ Finding the Right Cache +To reduce backend load and improve response times, we benchmarked multiple caching solutions—Memcached, KeyDB, and Dragonfly—under real production traffic patterns. Dragonfly stood out due to its robust architecture and operational simplicity:

+
    +
  • Data Skew Handling: Efficiently managed extreme key hotness and uneven access patterns without performance degradation.
  • +
  • Throughput: Delivered consistently high throughput, even with large object sizes and concurrent access.
  • +
  • Ease of Adoption: Acted as a drop-in Redis replacement with full protocol compatibility—no changes needed in application code or client libraries.
  • +
+

3️⃣ Moving to GoLang for Cost-Efficient Serving +Java services were memory-heavy—so we rewrote core services in GoLang. The results?

+

✅ Memory usage dropped by ~80% +✅ CPU utilization was significantly lower +✅ Faster, more efficient deployments

+

Optimizing the Interaction Store

+

We realized that we only need a user’s interaction data in Redis when they open the app. So, we implemented a tiered storage approach:

+
    +
  • 📌 Cold Tier (ScyllaDB)—Stores click, order, wishlist events
  • +
  • 📌 Hot Tier (Redis)—Loads a user’s past interactions only when they open the app
  • +
+

Smart Offloading: We introduced an inactivity tracker to detect when a user session ends. At that point, Redis data was flushed back to Scylla, reducing unnecessary writes.

+

InteractionStore

+

Results

+
    +
  • Online Feature Store hit 1M QPS for the first time during the 2023 Mega Blockbuster Sale—without breaking a sweat
  • +
  • Infra costs for Online Feature Store and Interaction Store dropped by ~60%
  • +
+

The Catch: Our ML Hosting Hit a Hard Limit

+

While planning for 2023 MBS, we ran into a critical scalability bottleneck:

+
    +
  • ❌ Insufficient compute availability in our region for ML instances
  • +
  • ❌ Couldn’t provision enough nodes to handle real-time inference at scale
  • +
+

This forced us to rethink where and how we hosted our models. The existing setup was great for prototyping—but it wasn’t built to handle the bursty, high-QPS demands of real-world production workloads.

+

Conclusion: From Firefighting to Future-Proofing

+

What started as an ambitious experiment turned into a real-time ML infrastructure that powered millions of requests per second. We battled scaling pains, rethought feature retrieval with Inferflow, and rebuilt our infra stack for efficiency—driving down costs while improving experimentation velocity. +But new challenges emerged. Our infrastructure could now handle scale, but our ML model hosting setup hit a hard limit. With compute availability bottlenecks threatening real-time inference, we faced a critical decision: how do we make model serving as scalable and cost-efficient as the rest of our stack? That’s the next piece of the puzzle—and the story of Part 3.

+ + \ No newline at end of file diff --git a/docs/blog/tags/interaction-store/index.html b/docs/blog/tags/interaction-store/index.html index 363b22a3..dfb1374a 100644 --- a/docs/blog/tags/interaction-store/index.html +++ b/docs/blog/tags/interaction-store/index.html @@ -3,16 +3,143 @@ -One post tagged with "interaction-store" | BharatMLStack - - - +2 posts tagged with "interaction-store" | BharatMLStack + + + -

One post tagged with "interaction-store"

View All Tags

Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1)

· 11 min read
Adarsha Das
Senior Architect @ Meesho
Aditya Kumar
SDE-III @ Meesho
Bhawani Singh
SDE-IV @ Meesho
Jigar Dave
SDE-IV @ Meesho

BharatMLStack

+

2 posts tagged with "interaction-store"

View All Tags

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

· 7 min read
Bhawani Singh
Architect @ Meesho
Jigar Dave
Lead Software Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

+

By late 2022, we had built something we were truly proud of—a real-time ML serving system with a DAG-based executor, a feature store, and an interaction store powering key ranking and personalization models. It was a major milestone, the culmination of months of effort from data scientists, ML engineers, and backend teams. Our system was live, and we were ready to push the boundaries of experimentation. +And it worked. Mostly. +But soon, cracks appeared. Every new model needed custom feature retrieval logic, DAGs became dense and unmanageable, and scaling turned into a constant firefight. Costs surged, and infra bottlenecks slowed experimentation. Our system worked, but it wasn’t built for scale. +This is the story of how we tackled these challenges—building Inferflow for seamless feature retrieval, optimizing real-time infra, and cutting costs while scaling to millions of QPS.

+

The Cost of Success

+

Every new Ranker model required its own feature set, often pulling from different entities. Each addition meant:

+
    +
  • Adding new DAG nodes in IOP
  • +
  • Writing custom logic to fetch features from multiple sources (e.g., user, product, user × category)
  • +
  • Inferring intermediate features (e.g., extracting category from a product to fetch user × category data)
  • +
  • Optimizing I/O and dealing with the inevitable bugs
  • +
+

What began as clean DAGs soon turned into a tangled web of cross-dependent graphs. Every experimentation cycle meant new nodes, new dependencies, and slower iterations.

+

Scaling Pains (and Cassandra’s Limits)

+

At some point, we were hitting:

+
    +
  • 250–300K reads/sec
  • +
  • 1M writes/sec (during lean hours)
  • +
+

All of this ran on Cassandra. While its distributed architecture had been proven in production, operating large-scale clusters came with considerable infrastructure overhead. Our proof-of-concept (POC) demonstrated throughput of around 100K ops/sec, but as we scaled further, the challenges grew. Ensuring node health, optimizing compaction, and maintaining storage balance became increasingly demanding. We also observed latency spikes under heavy load, alongside a sharp increase in total cost of ownership.

+

Interaction Store Woes

+

Our interaction store was another ticking time bomb:

+
    +
  • 🚨 Clusters kept growing in size and cost
  • +
  • 🚨 Latency spikes became increasingly frequent
  • +
  • 🚨 The DMC proxy occasionally lost locality of nodes against shards, causing cross-node communication and degraded performance
  • +
+

Each time this happened, we had to manually rebalance shards just to restore stable latency, making operations unsustainable at scale.

+

Silver Linings

+

Despite the chaos, the system was live and delivering value:

+
    +
  • Real-time infrastructure was in production
  • +
  • Costs dropped by 60–70% compared to offline personalization
  • +
  • New experiments rolled out faster and more successfully
  • +
  • User engagement metrics improved
  • +
+

It wasn’t perfect. It was far from easy. But it worked—and that counted for a lot.

+

Round Two: Solving the Top 2 Bottlenecks

+

With the first-gen system stretched to its limits, we stepped back. Conversations with data scientists and backend engineers revealed three recurring pain points:

+
    +
  1. Coding feature retrieval logic for every new model was becoming unsustainable
  2. +
  3. ML scale was exploding—bringing rising infra costs with it
  4. +
  5. Real-time embedding search was the next big unlock
  6. +
+

We tackled them one by one—starting with the biggest pain point.

+

Problem 1: No-Code Feature Retrieval for Model Inference

+

We noticed a pattern: for personalized ranking, models needed features from:

+
    +
  • ✅ Product
  • +
  • ✅ User
  • +
  • ✅ User × Category
  • +
  • ✅ Region, cohort, sub-category, etc.
  • +
+

A key insight emerged: Entities that contribute features for a model always map back to the context entities.

+

MP Dag

+

With this, we designed Inferflow, a graph-driven feature retrieval and model orchestration system:

+
    +
  • 1️⃣ Inferflow takes a modelId and context IDs (e.g., userId, productIds)
  • +
  • 2️⃣ Loads a pre-defined feature retrieval graph from ZooKeeper
  • +
  • 3️⃣ Executes the graph to resolve entity relationships dynamically
  • +
  • 4️⃣ Outputs a 2D matrix of feature vectors
  • +
+

💡 The impact?

+
    +
  • 🚀 No more custom feature retrieval code—just graph updates in config
  • +
  • 🚀 Feature consistency across experiments
  • +
  • 🚀 Faster iteration cycles for ranking, fraud detection, and beyond
  • +
+

Here’s a visual example that shows how this graph plays out during execution. We further extended the graph to call multiple models as needed: +MP matrix +We built Inferflow in GoLang, using gRPC and Proto3 serialization for efficiency.

+

Problem 2: Scaling Without Breaking the Bank

+

With more ML use cases coming online, we needed to cut costs without compromising performance. We focused on:

+
    +
  • 🔹 Online Feature Store
  • +
  • 🔹 Interaction Store
  • +
+

Optimizing the Online Feature Store

+

Our costs were concentrated in:

+
    +
  • 📌 Database (Cassandra)
  • +
  • 📌 Cache (Redis)
  • +
  • 📌 Running Pods (Java services)
  • +
+

1️⃣ Replacing Cassandra with ScyllaDB +As we hit the operational limits of large Cassandra clusters, we transitioned to ScyllaDB, which offered a seamless drop-in replacement without major code changes. The switch brought significant benefits:

+
    +
  • Throughput: Matched or exceeded Cassandra's performance under identical workloads, even under high concurrency.
  • +
  • Latency: Achieved consistently lower P99 latencies due to ScyllaDB's shard-per-core architecture and better I/O utilization.
  • +
  • Cost Efficiency: Reduced infra footprint by ~70% through better CPU and memory efficiency, eliminating the need for over-provisioned nodes.
  • +
+

2️⃣ Finding the Right Cache +To reduce backend load and improve response times, we benchmarked multiple caching solutions—Memcached, KeyDB, and Dragonfly—under real production traffic patterns. Dragonfly stood out due to its robust architecture and operational simplicity:

+
    +
  • Data Skew Handling: Efficiently managed extreme key hotness and uneven access patterns without performance degradation.
  • +
  • Throughput: Delivered consistently high throughput, even with large object sizes and concurrent access.
  • +
  • Ease of Adoption: Acted as a drop-in Redis replacement with full protocol compatibility—no changes needed in application code or client libraries.
  • +
+

3️⃣ Moving to GoLang for Cost-Efficient Serving +Java services were memory-heavy—so we rewrote core services in GoLang. The results?

+

✅ Memory usage dropped by ~80% +✅ CPU utilization was significantly lower +✅ Faster, more efficient deployments

+

Optimizing the Interaction Store

+

We realized that we only need a user’s interaction data in Redis when they open the app. So, we implemented a tiered storage approach:

+
    +
  • 📌 Cold Tier (ScyllaDB)—Stores click, order, wishlist events
  • +
  • 📌 Hot Tier (Redis)—Loads a user’s past interactions only when they open the app
  • +
+

Smart Offloading: We introduced an inactivity tracker to detect when a user session ends. At that point, Redis data was flushed back to Scylla, reducing unnecessary writes.

+

InteractionStore

+

Results

+
    +
  • Online Feature Store hit 1M QPS for the first time during the 2023 Mega Blockbuster Sale—without breaking a sweat
  • +
  • Infra costs for Online Feature Store and Interaction Store dropped by ~60%
  • +
+

The Catch: Our ML Hosting Hit a Hard Limit

+

While planning for 2023 MBS, we ran into a critical scalability bottleneck:

+
    +
  • ❌ Insufficient compute availability in our region for ML instances
  • +
  • ❌ Couldn’t provision enough nodes to handle real-time inference at scale
  • +
+

This forced us to rethink where and how we hosted our models. The existing setup was great for prototyping—but it wasn’t built to handle the bursty, high-QPS demands of real-world production workloads.

+

Conclusion: From Firefighting to Future-Proofing

+

What started as an ambitious experiment turned into a real-time ML infrastructure that powered millions of requests per second. We battled scaling pains, rethought feature retrieval with Inferflow, and rebuilt our infra stack for efficiency—driving down costs while improving experimentation velocity. +But new challenges emerged. Our infrastructure could now handle scale, but our ML model hosting setup hit a hard limit. With compute availability bottlenecks threatening real-time inference, we faced a critical decision: how do we make model serving as scalable and cost-efficient as the rest of our stack? That’s the next piece of the puzzle—and the story of Part 3.

Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1)

· 11 min read
Adarsha Das
Senior Architect @ Meesho
Aditya Kumar
Lead Software Engineer @ Meesho
Bhawani Singh
Architect @ Meesho
Jigar Dave
Lead Software Engineer @ Meesho

BharatMLStack

The Genesis: How a Friday Night Roast Sparked Meesho’s ML Platform

It all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting—until one remark hit a little too close to home:

"Why are we still crunching data for Monthly Active Users (MAU) when the next day it’s all about Daily Active Users (DAU)?"

@@ -204,6 +331,6 @@

+

This foundational work laid the path for a reliable and scalable real-time feature serving layer.

\ No newline at end of file diff --git a/docs/blog/tags/llm/index.html b/docs/blog/tags/llm/index.html new file mode 100644 index 00000000..f13ce660 --- /dev/null +++ b/docs/blog/tags/llm/index.html @@ -0,0 +1,157 @@ + + + + + +2 posts tagged with "llm" | BharatMLStack + + + + + + + + +

2 posts tagged with "llm"

View All Tags

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

· 5 min read
Jaya Kumar
Lead ML Engineer @ Meesho

BharatMLStack

+

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

+

Raw execution of Large Language Models is inherently expensive and memory-intensive. To achieve sub-second latency and high throughput, we implement a multi-layered optimization strategy that targets the entire inference stack—from memory management to kernel execution.

+

1. Advanced Memory Management: Paged & Prefix KV Caching

+

The most significant bottleneck in LLM inference is not always compute, but memory bandwidth—specifically managing the Key-Value (KV) cache.

+

Paged KV caching

+

Standard caching suffers from fragmentation. We use Paged KV caching, which operates similarly to an operating system's virtual memory: the KV cache is divided into non-contiguous blocks. This lets us serve larger batch sizes without running out of memory.

+

KV cache quantization

+

To further maximize available memory, we implement KV cache quantization (e.g., FP8). By compressing stored attention keys and values from 16-bit to 8-bit, we nearly double the effective context window capacity of the GPU, allowing longer conversations or larger batches without materially degrading quality.

+

Prefix caching (the "voice bot" optimizer)

+

For use cases like GenAI voice bots where the system prompt (e.g., "You are a helpful assistant...") is static across thousands of requests, we enable prefix caching.

+
    +
  • Impact: By reusing pre-computed KV states for common prefixes, we achieve a cache hit rate of ~90%. This reduces Time To First Token (TTFT) by skipping redundant computation of the system prompt.
  • +
+

2. Aggressive Quantization (INT4 AWQ & FP8)

+

Running models in their native 16-bit precision (BF16) restricts maximum batch size and throughput. We use quantization to shrink model weights without sacrificing accuracy.

+

INT4 AWQ (Activation-aware Weight Quantization)

+

For the Llama 3 family, we use AWQ to compress weights to 4 bits. This reduces model size by ~75%, allowing larger models to fit into L4 GPU memory and significantly improving token generation speed.

+

FP8 precision

+

For NVIDIA Hopper (H100) architectures, we are exploring FP8 quantization, leveraging native FP8 tensor cores to accelerate matrix multiplications while maintaining a higher dynamic range than integer quantization.

+
    +
  • Verification: We validate quantized models by comparing dot-product similarity of embeddings against the FP16 baseline, consistently achieving >99% similarity.
  • +
+

3. Kernel Fusion & Custom Plugins

+

To minimize overhead from launching thousands of small GPU operations, we fuse them into monolithic kernels using NVIDIA TensorRT plugins.

+
    +
  • Flash attention & FMHA: We enable Fused Multi-Head Attention (FMHA) combined with flash attention to reduce memory reads/writes.
  • +
  • GEMM plugins: We use specialized GEMM plugins to accelerate transformer linear layers.
  • +
  • Removing input padding: Instead of padding short sequences to match the longest, we remove input padding so the GPU processes only valid tokens.
  • +
+

4. Inflight (Continuous) Batching

+

Traditional static batching waits for all requests in a batch to finish before returning results—so one long response delays everyone else.

+

We implement inflight batching: as soon as one request completes, its slot is freed and filled by a new request from the queue. This keeps GPUs saturated and decouples latency of short queries from long ones.

+

5. Parallelism Strategies: Scaling Beyond One GPU

+

For large models (e.g., 70B+ parameters) that cannot fit into the VRAM of a single GPU, we use parallelism strategies.

+
    +
  • Tensor parallelism (TP): Split weight matrices across multiple GPUs (e.g., 4× L4 or 8× A100). Each GPU computes a shard and outputs are reduced at every layer.
  • +
  • Pipeline parallelism (PP): Split model layers across GPUs to pipeline compute (e.g., while one GPU computes later layers for Request A, another starts early layers for Request B).
  • +
+

6. Speculative Decoding

+

To reduce inter-token latency (ITL), we explore speculative decoding.

+
    +
  • Mechanism: A smaller, faster "draft" model speculatively generates a short token sequence (e.g., 5 tokens).
  • +
  • Verification: The larger target model verifies those tokens in one parallel forward pass. If correct, we effectively generate multiple tokens per large-model step; if not, we discard and regenerate. This is effective for predictable text, improving perceived generation speed.
  • +
+

Few Benchmarks

+

Below are a couple of representative use cases and performance numbers.

+

Search query rewriting

+
    +
  • LLM: Fine-tuned llama-3.2-1B
  • +
  • Input & output token length: ~10–20
  • +
  • Response type: Non-streaming
  • +
+
Inference runtimeHardwareMax requests/secMax p99 latency
TensorRT-LLM4 × L4 GPUs (multi-GPU)100095 ms
TensorRT-LLM1 × A100 40 GB GPU100069 ms
+

Voice bot query

+
    +
  • LLM: Llama-3.1-8B
  • +
  • Input token length: ~1900–2000
  • +
  • Output token length: ~200
  • +
  • Response type: Streaming
  • +
+
Inference runtimeConcurrencyp99 TTFT (ms)p99 ITL (ms)Token throughput (tokens/sec)Request throughput (req/sec)Hardware
TensorRT-LLM136.2722.7845.660.23L4
TensorRT-LLM249.8123.2189.370.45L4
TensorRT-LLM455.3336.62153.390.78L4
TensorRT-LLM866.539.11279.881.47L4
TensorRT-LLM16131.830.39547.82.77L4
TensorRT-LLM32277.2248.02925.74.78L4
TensorRT-LLM64498.5271.621,164.406.2L4
TensorRT-LLM128677.31120.371,445.187.69L4
TensorRT-LLM2561,926.31216.881,600.818.52L4
TensorRT-LLM121.179.24130.050.68A100
TensorRT-LLM225.789.21264.51.35A100
TensorRT-LLM428.5210.99437.692.27A100
TensorRT-LLM834.412.61760.493.96A100
TensorRT-LLM1668.0314.321,343.807.01A100
TensorRT-LLM32185.9616.822,287.3011.92A100
TensorRT-LLM64136.8721.173,625.2218.89A100
TensorRT-LLM128463.7834.154,456.5123.24A100
TensorRT-LLM256890.1259.185,188.2427.05A100
+

Conclusion

+

High-performance LLM inference is fundamentally a systems engineering problem: memory efficiency, kernel execution, batching strategy, and parallelism determine real-world latency and throughput. Techniques such as paged KV caching, aggressive quantization, kernel fusion, and inflight batching improve GPU utilization while reducing latency and memory pressure.

+

These optimizations enable the platform to deliver sub-second responses, sustain high concurrency, and efficiently serve both lightweight and long-context workloads. By continuously optimizing across the full inference stack, we keep LLM serving scalable, cost-efficient, and production-ready for real-time AI applications.

Cracking the Code: Scaling Model Inference & Real-Time Embedding Search

· 4 min read
Aditya Kumar
Lead Software Engineer @ Meesho
Jaya Kumar
Lead ML Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+ +

By mid-2023, we had transformed our ML stack—building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:

+
    +
  • 🔹 Scaling model inference without hitting infrastructure roadblocks
  • +
  • 🔹 Moving embedding search from batch to real-time for candidate generation
  • +
+

Here’s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system.

+

Breaking Free from the Scalability Ceiling

+

The Model Serving Bottleneck—A Wake-Up Call

+

July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue—scaling our model-serving infrastructure was taking 10–15 minutes. In real-time ML, that’s an eternity. +In one of our war rooms, we ran a quick experiment:

+
    +
  • 🚀 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine.
  • +
  • 🚀 Fired requests and compared the outputs with our existing cloud-hosted setup.
  • +
  • 🚀 The results matched—perfectly.
  • +
+

That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn't allocate enough compute resources in time. Luckily, they did—but the seed was planted. +Then in October, just two weeks before MBS, we got an alarming response from our infrastructure team: +"Node availability may be an issue." +With no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?

+
    +
  • ✅ p99 latency dropped from 90–100ms to 30–40ms
  • +
  • ✅ Triton handled significantly higher throughput on fewer resources
  • +
  • ✅ No model changes were needed
  • +
+

MBS ran without a hitch, proving that self-hosted inference was the way forward.

+

Scaling Triton on GKE

+

This left us with two choices:

+
    +
  • 1️⃣ Port models to a managed cloud inference service, investing time in learning a new deployment stack
  • +
  • 2️⃣ Scale our existing Triton setup on GKE, optimizing for cost and performance
  • +
+

We went with Option 2—and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations.

+

Fixing the Cold Start Problem

+

As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7–9 minutes to spin up.

+

After profiling, we found the culprits:

+
    +
  • Triton’s base image—a massive 5GB
  • +
  • Model binaries—often 1GB+
  • +
  • Startup delay—mostly due to downloading and initializing these assets
  • +
+

To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother.

+

Embedding Search: The Last Piece of the Puzzle

+

By mid-2023, most of our ML stack had gone real-time—except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system.

+

Choosing the Right Vector Database

+

We benchmarked three production-ready vector DBs across key parameters:

+
    +
  • Milvus
  • +
  • Qdrant
  • +
  • Weaviate
  • +
+

After extensive POCs, Qdrant stood out for its:

+
    +
  • ✅ Blazing-fast search latency on high-dimensional vectors
  • +
  • ✅ Efficient memory usage, crucial for in-memory workloads
  • +
  • ✅ Support for upserts and soft deletes, vital for Ads use cases
  • +
  • ✅ gRPC + REST APIs, making integration seamless
  • +
  • ✅ Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)
  • +
+

At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search—a perfect fit for our needs.

+

Embedding Freshness & Real-Time Updates

+

To ensure embeddings stayed up to date, we built a dual ingestion pipeline:

+
    +
  • 📌 Daily Refresh: A bulk pipeline updated embeddings overnight
  • +
  • 📌 Real-Time Updates: Ads events triggered immediate upserts/deletes
  • +
+

This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.

+

Skye

+

Final Takeaways: Scaling Smartly for Real-Time ML

+
    +
  • 🚀 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services
  • +
  • 🚀 Building a custom Triton image reduced cold starts, improving responsiveness
  • +
  • 🚀 Qdrant-based embedding search enabled real-time personalization at scale
  • +
  • 🚀 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations
  • +
+

By early 2024, Meesho’s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead.

+ + \ No newline at end of file diff --git a/docs/blog/tags/meesho/index.html b/docs/blog/tags/meesho/index.html index f74846f7..373157df 100644 --- a/docs/blog/tags/meesho/index.html +++ b/docs/blog/tags/meesho/index.html @@ -3,16 +3,359 @@ -One post tagged with "meesho" | BharatMLStack - - - +5 posts tagged with "meesho" | BharatMLStack + + + -

One post tagged with "meesho"

View All Tags

Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1)

· 11 min read
Adarsha Das
Senior Architect @ Meesho
Aditya Kumar
SDE-III @ Meesho
Bhawani Singh
SDE-IV @ Meesho
Jigar Dave
SDE-IV @ Meesho

BharatMLStack

+

5 posts tagged with "meesho"

View All Tags

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

· 5 min read
Jaya Kumar
Lead ML Engineer @ Meesho

BharatMLStack

+

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

+

Raw execution of Large Language Models is inherently expensive and memory-intensive. To achieve sub-second latency and high throughput, we implement a multi-layered optimization strategy that targets the entire inference stack—from memory management to kernel execution.

+

1. Advanced Memory Management: Paged & Prefix KV Caching

+

The most significant bottleneck in LLM inference is not always compute, but memory bandwidth—specifically managing the Key-Value (KV) cache.

+

Paged KV caching

+

Standard caching suffers from fragmentation. We use Paged KV caching, which operates similarly to an operating system's virtual memory: the KV cache is divided into non-contiguous blocks. This lets us serve larger batch sizes without running out of memory.

+

KV cache quantization

+

To further maximize available memory, we implement KV cache quantization (e.g., FP8). By compressing stored attention keys and values from 16-bit to 8-bit, we nearly double the effective context window capacity of the GPU, allowing longer conversations or larger batches without materially degrading quality.

+

Prefix caching (the "voice bot" optimizer)

+

For use cases like GenAI voice bots where the system prompt (e.g., "You are a helpful assistant...") is static across thousands of requests, we enable prefix caching.

+
    +
  • Impact: By reusing pre-computed KV states for common prefixes, we achieve a cache hit rate of ~90%. This reduces Time To First Token (TTFT) by skipping redundant computation of the system prompt.
  • +
+

2. Aggressive Quantization (INT4 AWQ & FP8)

+

Running models in their native 16-bit precision (BF16) restricts maximum batch size and throughput. We use quantization to shrink model weights without sacrificing accuracy.

+

INT4 AWQ (Activation-aware Weight Quantization)

+

For the Llama 3 family, we use AWQ to compress weights to 4 bits. This reduces model size by ~75%, allowing larger models to fit into L4 GPU memory and significantly improving token generation speed.

+

FP8 precision

+

For NVIDIA Hopper (H100) architectures, we are exploring FP8 quantization, leveraging native FP8 tensor cores to accelerate matrix multiplications while maintaining a higher dynamic range than integer quantization.

+
    +
  • Verification: We validate quantized models by comparing dot-product similarity of embeddings against the FP16 baseline, consistently achieving >99% similarity.
  • +
+

3. Kernel Fusion & Custom Plugins

+

To minimize overhead from launching thousands of small GPU operations, we fuse them into monolithic kernels using NVIDIA TensorRT plugins.

+
    +
  • Flash attention & FMHA: We enable Fused Multi-Head Attention (FMHA) combined with flash attention to reduce memory reads/writes.
  • +
  • GEMM plugins: We use specialized GEMM plugins to accelerate transformer linear layers.
  • +
  • Removing input padding: Instead of padding short sequences to match the longest, we remove input padding so the GPU processes only valid tokens.
  • +
+

4. Inflight (Continuous) Batching

+

Traditional static batching waits for all requests in a batch to finish before returning results—so one long response delays everyone else.

+

We implement inflight batching: as soon as one request completes, its slot is freed and filled by a new request from the queue. This keeps GPUs saturated and decouples latency of short queries from long ones.

+

5. Parallelism Strategies: Scaling Beyond One GPU

+

For large models (e.g., 70B+ parameters) that cannot fit into the VRAM of a single GPU, we use parallelism strategies.

+
    +
  • Tensor parallelism (TP): Split weight matrices across multiple GPUs (e.g., 4× L4 or 8× A100). Each GPU computes a shard and outputs are reduced at every layer.
  • +
  • Pipeline parallelism (PP): Split model layers across GPUs to pipeline compute (e.g., while one GPU computes later layers for Request A, another starts early layers for Request B).
  • +
+

6. Speculative Decoding

+

To reduce inter-token latency (ITL), we explore speculative decoding.

+
    +
  • Mechanism: A smaller, faster "draft" model speculatively generates a short token sequence (e.g., 5 tokens).
  • +
  • Verification: The larger target model verifies those tokens in one parallel forward pass. If correct, we effectively generate multiple tokens per large-model step; if not, we discard and regenerate. This is effective for predictable text, improving perceived generation speed.
  • +
+

Few Benchmarks

+

Below are a couple of representative use cases and performance numbers.

+

Search query rewriting

+
    +
  • LLM: Fine-tuned llama-3.2-1B
  • +
  • Input & output token length: ~10–20
  • +
  • Response type: Non-streaming
  • +
+
Inference runtimeHardwareMax requests/secMax p99 latency
TensorRT-LLM4 × L4 GPUs (multi-GPU)100095 ms
TensorRT-LLM1 × A100 40 GB GPU100069 ms
+

Voice bot query

+
    +
  • LLM: Llama-3.1-8B
  • +
  • Input token length: ~1900–2000
  • +
  • Output token length: ~200
  • +
  • Response type: Streaming
  • +
+
Inference runtimeConcurrencyp99 TTFT (ms)p99 ITL (ms)Token throughput (tokens/sec)Request throughput (req/sec)Hardware
TensorRT-LLM136.2722.7845.660.23L4
TensorRT-LLM249.8123.2189.370.45L4
TensorRT-LLM455.3336.62153.390.78L4
TensorRT-LLM866.539.11279.881.47L4
TensorRT-LLM16131.830.39547.82.77L4
TensorRT-LLM32277.2248.02925.74.78L4
TensorRT-LLM64498.5271.621,164.406.2L4
TensorRT-LLM128677.31120.371,445.187.69L4
TensorRT-LLM2561,926.31216.881,600.818.52L4
TensorRT-LLM121.179.24130.050.68A100
TensorRT-LLM225.789.21264.51.35A100
TensorRT-LLM428.5210.99437.692.27A100
TensorRT-LLM834.412.61760.493.96A100
TensorRT-LLM1668.0314.321,343.807.01A100
TensorRT-LLM32185.9616.822,287.3011.92A100
TensorRT-LLM64136.8721.173,625.2218.89A100
TensorRT-LLM128463.7834.154,456.5123.24A100
TensorRT-LLM256890.1259.185,188.2427.05A100
+

Conclusion

+

High-performance LLM inference is fundamentally a systems engineering problem: memory efficiency, kernel execution, batching strategy, and parallelism determine real-world latency and throughput. Techniques such as paged KV caching, aggressive quantization, kernel fusion, and inflight batching improve GPU utilization while reducing latency and memory pressure.

+

These optimizations enable the platform to deliver sub-second responses, sustain high concurrency, and efficiently serve both lightweight and long-context workloads. By continuously optimizing across the full inference stack, we keep LLM serving scalable, cost-efficient, and production-ready for real-time AI applications.

Cracking the Code: Scaling Model Inference & Real-Time Embedding Search

· 4 min read
Aditya Kumar
Lead Software Engineer @ Meesho
Jaya Kumar
Lead ML Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+ +

By mid-2023, we had transformed our ML stack—building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:

+
    +
  • 🔹 Scaling model inference without hitting infrastructure roadblocks
  • +
  • 🔹 Moving embedding search from batch to real-time for candidate generation
  • +
+

Here’s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system.

+

Breaking Free from the Scalability Ceiling

+

The Model Serving Bottleneck—A Wake-Up Call

+

July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue—scaling our model-serving infrastructure was taking 10–15 minutes. In real-time ML, that’s an eternity. +In one of our war rooms, we ran a quick experiment:

+
    +
  • 🚀 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine.
  • +
  • 🚀 Fired requests and compared the outputs with our existing cloud-hosted setup.
  • +
  • 🚀 The results matched—perfectly.
  • +
+

That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn't allocate enough compute resources in time. Luckily, they did—but the seed was planted. +Then in October, just two weeks before MBS, we got an alarming response from our infrastructure team: +"Node availability may be an issue." +With no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?

+
    +
  • ✅ p99 latency dropped from 90–100ms to 30–40ms
  • +
  • ✅ Triton handled significantly higher throughput on fewer resources
  • +
  • ✅ No model changes were needed
  • +
+

MBS ran without a hitch, proving that self-hosted inference was the way forward.

+

Scaling Triton on GKE

+

This left us with two choices:

+
    +
  • 1️⃣ Port models to a managed cloud inference service, investing time in learning a new deployment stack
  • +
  • 2️⃣ Scale our existing Triton setup on GKE, optimizing for cost and performance
  • +
+

We went with Option 2—and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations.

+

Fixing the Cold Start Problem

+

As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7–9 minutes to spin up.

+

After profiling, we found the culprits:

+
    +
  • Triton’s base image—a massive 5GB
  • +
  • Model binaries—often 1GB+
  • +
  • Startup delay—mostly due to downloading and initializing these assets
  • +
+

To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother.

+

Embedding Search: The Last Piece of the Puzzle

+

By mid-2023, most of our ML stack had gone real-time—except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system.

+

Choosing the Right Vector Database

+

We benchmarked three production-ready vector DBs across key parameters:

+
    +
  • Milvus
  • +
  • Qdrant
  • +
  • Weaviate
  • +
+

After extensive POCs, Qdrant stood out for its:

+
    +
  • ✅ Blazing-fast search latency on high-dimensional vectors
  • +
  • ✅ Efficient memory usage, crucial for in-memory workloads
  • +
  • ✅ Support for upserts and soft deletes, vital for Ads use cases
  • +
  • ✅ gRPC + REST APIs, making integration seamless
  • +
  • ✅ Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)
  • +
+

At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search—a perfect fit for our needs.

+

Embedding Freshness & Real-Time Updates

+

To ensure embeddings stayed up to date, we built a dual ingestion pipeline:

+
    +
  • 📌 Daily Refresh: A bulk pipeline updated embeddings overnight
  • +
  • 📌 Real-Time Updates: Ads events triggered immediate upserts/deletes
  • +
+

This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.

+

Skye

+

Final Takeaways: Scaling Smartly for Real-Time ML

+
    +
  • 🚀 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services
  • +
  • 🚀 Building a custom Triton image reduced cold starts, improving responsiveness
  • +
  • 🚀 Qdrant-based embedding search enabled real-time personalization at scale
  • +
  • 🚀 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations
  • +
+

By early 2024, Meesho’s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead.

Cracking the Code: Scaling Model Inference & Real-Time Embedding Search

· 4 min read
Aditya Kumar
Lead Software Engineer @ Meesho
Jaya Kumar
Lead ML Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+ +

By mid-2023, we had transformed our ML stack—building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:

+
    +
  • 🔹 Scaling model inference without hitting infrastructure roadblocks
  • +
  • 🔹 Moving embedding search from batch to real-time for candidate generation
  • +
+

Here’s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system.

+

Breaking Free from the Scalability Ceiling

+

The Model Serving Bottleneck—A Wake-Up Call

+

July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue—scaling our model-serving infrastructure was taking 10–15 minutes. In real-time ML, that’s an eternity. +In one of our war rooms, we ran a quick experiment:

+
    +
  • 🚀 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine.
  • +
  • 🚀 Fired requests and compared the outputs with our existing cloud-hosted setup.
  • +
  • 🚀 The results matched—perfectly.
  • +
+

That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn't allocate enough compute resources in time. Luckily, they did—but the seed was planted. +Then in October, just two weeks before MBS, we got an alarming response from our infrastructure team: +"Node availability may be an issue." +With no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?

+
    +
  • ✅ p99 latency dropped from 90–100ms to 30–40ms
  • +
  • ✅ Triton handled significantly higher throughput on fewer resources
  • +
  • ✅ No model changes were needed
  • +
+

MBS ran without a hitch, proving that self-hosted inference was the way forward.

+

Scaling Triton on GKE

+

This left us with two choices:

+
    +
  • 1️⃣ Port models to a managed cloud inference service, investing time in learning a new deployment stack
  • +
  • 2️⃣ Scale our existing Triton setup on GKE, optimizing for cost and performance
  • +
+

We went with Option 2—and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations.

+

Fixing the Cold Start Problem

+

As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7–9 minutes to spin up.

+

After profiling, we found the culprits:

+
    +
  • Triton’s base image—a massive 5GB
  • +
  • Model binaries—often 1GB+
  • +
  • Startup delay—mostly due to downloading and initializing these assets
  • +
+

To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother.

+

Embedding Search: The Last Piece of the Puzzle

+

By mid-2023, most of our ML stack had gone real-time—except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system.

+

Choosing the Right Vector Database

+

We benchmarked three production-ready vector DBs across key parameters:

+
    +
  • Milvus
  • +
  • Qdrant
  • +
  • Weaviate
  • +
+

After extensive POCs, Qdrant stood out for its:

+
    +
  • ✅ Blazing-fast search latency on high-dimensional vectors
  • +
  • ✅ Efficient memory usage, crucial for in-memory workloads
  • +
  • ✅ Support for upserts and soft deletes, vital for Ads use cases
  • +
  • ✅ gRPC + REST APIs, making integration seamless
  • +
  • ✅ Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)
  • +
+

At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search—a perfect fit for our needs.

+

Embedding Freshness & Real-Time Updates

+

To ensure embeddings stayed up to date, we built a dual ingestion pipeline:

+
    +
  • 📌 Daily Refresh: A bulk pipeline updated embeddings overnight
  • +
  • 📌 Real-Time Updates: Ads events triggered immediate upserts/deletes
  • +
+

This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.

+

Skye

+

Final Takeaways: Scaling Smartly for Real-Time ML

+
    +
  • 🚀 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services
  • +
  • 🚀 Building a custom Triton image reduced cold starts, improving responsiveness
  • +
  • 🚀 Qdrant-based embedding search enabled real-time personalization at scale
  • +
  • 🚀 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations
  • +
+

By early 2024, Meesho’s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead.

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

· 7 min read
Bhawani Singh
Architect @ Meesho
Jigar Dave
Lead Software Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

+

By late 2022, we had built something we were truly proud of—a real-time ML serving system with a DAG-based executor, a feature store, and an interaction store powering key ranking and personalization models. It was a major milestone, the culmination of months of effort from data scientists, ML engineers, and backend teams. Our system was live, and we were ready to push the boundaries of experimentation. +And it worked. Mostly. +But soon, cracks appeared. Every new model needed custom feature retrieval logic, DAGs became dense and unmanageable, and scaling turned into a constant firefight. Costs surged, and infra bottlenecks slowed experimentation. Our system worked, but it wasn’t built for scale. +This is the story of how we tackled these challenges—building Inferflow for seamless feature retrieval, optimizing real-time infra, and cutting costs while scaling to millions of QPS.

+

The Cost of Success

+

Every new Ranker model required its own feature set, often pulling from different entities. Each addition meant:

+
    +
  • Adding new DAG nodes in IOP
  • +
  • Writing custom logic to fetch features from multiple sources (e.g., user, product, user × category)
  • +
  • Inferring intermediate features (e.g., extracting category from a product to fetch user × category data)
  • +
  • Optimizing I/O and dealing with the inevitable bugs
  • +
+

What began as clean DAGs soon turned into a tangled web of cross-dependent graphs. Every experimentation cycle meant new nodes, new dependencies, and slower iterations.

+

Scaling Pains (and Cassandra’s Limits)

+

At some point, we were hitting:

+
    +
  • 250–300K reads/sec
  • +
  • 1M writes/sec (during lean hours)
  • +
+

All of this ran on Cassandra. While its distributed architecture had been proven in production, operating large-scale clusters came with considerable infrastructure overhead. Our proof-of-concept (POC) demonstrated throughput of around 100K ops/sec, but as we scaled further, the challenges grew. Ensuring node health, optimizing compaction, and maintaining storage balance became increasingly demanding. We also observed latency spikes under heavy load, alongside a sharp increase in total cost of ownership.

+

Interaction Store Woes

+

Our interaction store was another ticking time bomb:

+
    +
  • 🚨 Clusters kept growing in size and cost
  • +
  • 🚨 Latency spikes became increasingly frequent
  • +
  • 🚨 The DMC proxy occasionally lost locality of nodes against shards, causing cross-node communication and degraded performance
  • +
+

Each time this happened, we had to manually rebalance shards just to restore stable latency, making operations unsustainable at scale.

+

Silver Linings

+

Despite the chaos, the system was live and delivering value:

+
    +
  • Real-time infrastructure was in production
  • +
  • Costs dropped by 60–70% compared to offline personalization
  • +
  • New experiments rolled out faster and more successfully
  • +
  • User engagement metrics improved
  • +
+

It wasn’t perfect. It was far from easy. But it worked—and that counted for a lot.

+

Round Two: Solving the Top 2 Bottlenecks

+

With the first-gen system stretched to its limits, we stepped back. Conversations with data scientists and backend engineers revealed three recurring pain points:

+
    +
  1. Coding feature retrieval logic for every new model was becoming unsustainable
  2. +
  3. ML scale was exploding—bringing rising infra costs with it
  4. +
  5. Real-time embedding search was the next big unlock
  6. +
+

We tackled them one by one—starting with the biggest pain point.

+

Problem 1: No-Code Feature Retrieval for Model Inference

+

We noticed a pattern: for personalized ranking, models needed features from:

+
    +
  • ✅ Product
  • +
  • ✅ User
  • +
  • ✅ User × Category
  • +
  • ✅ Region, cohort, sub-category, etc.
  • +
+

A key insight emerged: Entities that contribute features for a model always map back to the context entities.

+

MP Dag

+

With this, we designed Inferflow, a graph-driven feature retrieval and model orchestration system:

+
    +
  • 1️⃣ Inferflow takes a modelId and context IDs (e.g., userId, productIds)
  • +
  • 2️⃣ Loads a pre-defined feature retrieval graph from ZooKeeper
  • +
  • 3️⃣ Executes the graph to resolve entity relationships dynamically
  • +
  • 4️⃣ Outputs a 2D matrix of feature vectors
  • +
+

💡 The impact?

+
    +
  • 🚀 No more custom feature retrieval code—just graph updates in config
  • +
  • 🚀 Feature consistency across experiments
  • +
  • 🚀 Faster iteration cycles for ranking, fraud detection, and beyond
  • +
+

Here’s a visual example that shows how this graph plays out during execution. We further extended the graph to call multiple models as needed: +MP matrix +We built Inferflow in GoLang, using gRPC and Proto3 serialization for efficiency.

+

Problem 2: Scaling Without Breaking the Bank

+

With more ML use cases coming online, we needed to cut costs without compromising performance. We focused on:

+
    +
  • 🔹 Online Feature Store
  • +
  • 🔹 Interaction Store
  • +
+

Optimizing the Online Feature Store

+

Our costs were concentrated in:

+
    +
  • 📌 Database (Cassandra)
  • +
  • 📌 Cache (Redis)
  • +
  • 📌 Running Pods (Java services)
  • +
+

1️⃣ Replacing Cassandra with ScyllaDB +As we hit the operational limits of large Cassandra clusters, we transitioned to ScyllaDB, which offered a seamless drop-in replacement without major code changes. The switch brought significant benefits:

+
    +
  • Throughput: Matched or exceeded Cassandra's performance under identical workloads, even under high concurrency.
  • +
  • Latency: Achieved consistently lower P99 latencies due to ScyllaDB's shard-per-core architecture and better I/O utilization.
  • +
  • Cost Efficiency: Reduced infra footprint by ~70% through better CPU and memory efficiency, eliminating the need for over-provisioned nodes.
  • +
+

2️⃣ Finding the Right Cache +To reduce backend load and improve response times, we benchmarked multiple caching solutions—Memcached, KeyDB, and Dragonfly—under real production traffic patterns. Dragonfly stood out due to its robust architecture and operational simplicity:

+
    +
  • Data Skew Handling: Efficiently managed extreme key hotness and uneven access patterns without performance degradation.
  • +
  • Throughput: Delivered consistently high throughput, even with large object sizes and concurrent access.
  • +
  • Ease of Adoption: Acted as a drop-in Redis replacement with full protocol compatibility—no changes needed in application code or client libraries.
  • +
+

3️⃣ Moving to GoLang for Cost-Efficient Serving +Java services were memory-heavy—so we rewrote core services in GoLang. The results?

+

✅ Memory usage dropped by ~80% +✅ CPU utilization was significantly lower +✅ Faster, more efficient deployments

+

Optimizing the Interaction Store

+

We realized that we only need a user’s interaction data in Redis when they open the app. So, we implemented a tiered storage approach:

+
    +
  • 📌 Cold Tier (ScyllaDB)—Stores click, order, wishlist events
  • +
  • 📌 Hot Tier (Redis)—Loads a user’s past interactions only when they open the app
  • +
+

Smart Offloading: We introduced an inactivity tracker to detect when a user session ends. At that point, Redis data was flushed back to Scylla, reducing unnecessary writes.

+

InteractionStore

+

Results

+
    +
  • Online Feature Store hit 1M QPS for the first time during the 2023 Mega Blockbuster Sale—without breaking a sweat
  • +
  • Infra costs for Online Feature Store and Interaction Store dropped by ~60%
  • +
+

The Catch: Our ML Hosting Hit a Hard Limit

+

While planning for 2023 MBS, we ran into a critical scalability bottleneck:

+
    +
  • ❌ Insufficient compute availability in our region for ML instances
  • +
  • ❌ Couldn’t provision enough nodes to handle real-time inference at scale
  • +
+

This forced us to rethink where and how we hosted our models. The existing setup was great for prototyping—but it wasn’t built to handle the bursty, high-QPS demands of real-world production workloads.

+

Conclusion: From Firefighting to Future-Proofing

+

What started as an ambitious experiment turned into a real-time ML infrastructure that powered millions of requests per second. We battled scaling pains, rethought feature retrieval with Inferflow, and rebuilt our infra stack for efficiency—driving down costs while improving experimentation velocity. +But new challenges emerged. Our infrastructure could now handle scale, but our ML model hosting setup hit a hard limit. With compute availability bottlenecks threatening real-time inference, we faced a critical decision: how do we make model serving as scalable and cost-efficient as the rest of our stack? That’s the next piece of the puzzle—and the story of Part 3.

Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1)

· 11 min read
Adarsha Das
Senior Architect @ Meesho
Aditya Kumar
Lead Software Engineer @ Meesho
Bhawani Singh
Architect @ Meesho
Jigar Dave
Lead Software Engineer @ Meesho

BharatMLStack

The Genesis: How a Friday Night Roast Sparked Meesho’s ML Platform

It all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting—until one remark hit a little too close to home:

"Why are we still crunching data for Monthly Active Users (MAU) when the next day it’s all about Daily Active Users (DAU)?"

@@ -204,6 +547,6 @@

+

This foundational work laid the path for a reliable and scalable real-time feature serving layer.

\ No newline at end of file diff --git a/docs/blog/tags/mlplatform/index.html b/docs/blog/tags/mlplatform/index.html index ec91f7f9..ce749519 100644 --- a/docs/blog/tags/mlplatform/index.html +++ b/docs/blog/tags/mlplatform/index.html @@ -3,16 +3,359 @@ -One post tagged with "mlplatform" | BharatMLStack - - - +5 posts tagged with "mlplatform" | BharatMLStack + + + -

One post tagged with "mlplatform"

View All Tags

Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1)

· 11 min read
Adarsha Das
Senior Architect @ Meesho
Aditya Kumar
SDE-III @ Meesho
Bhawani Singh
SDE-IV @ Meesho
Jigar Dave
SDE-IV @ Meesho

BharatMLStack

+

5 posts tagged with "mlplatform"

View All Tags

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

· 5 min read
Jaya Kumar
Lead ML Engineer @ Meesho

BharatMLStack

+

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

+

Raw execution of Large Language Models is inherently expensive and memory-intensive. To achieve sub-second latency and high throughput, we implement a multi-layered optimization strategy that targets the entire inference stack—from memory management to kernel execution.

+

1. Advanced Memory Management: Paged & Prefix KV Caching

+

The most significant bottleneck in LLM inference is not always compute, but memory bandwidth—specifically managing the Key-Value (KV) cache.

+

Paged KV caching

+

Standard caching suffers from fragmentation. We use Paged KV caching, which operates similarly to an operating system's virtual memory: the KV cache is divided into non-contiguous blocks. This lets us serve larger batch sizes without running out of memory.

+

KV cache quantization

+

To further maximize available memory, we implement KV cache quantization (e.g., FP8). By compressing stored attention keys and values from 16-bit to 8-bit, we nearly double the effective context window capacity of the GPU, allowing longer conversations or larger batches without materially degrading quality.

+

Prefix caching (the "voice bot" optimizer)

+

For use cases like GenAI voice bots where the system prompt (e.g., "You are a helpful assistant...") is static across thousands of requests, we enable prefix caching.

+
    +
  • Impact: By reusing pre-computed KV states for common prefixes, we achieve a cache hit rate of ~90%. This reduces Time To First Token (TTFT) by skipping redundant computation of the system prompt.
  • +
+

2. Aggressive Quantization (INT4 AWQ & FP8)

+

Running models in their native 16-bit precision (BF16) restricts maximum batch size and throughput. We use quantization to shrink model weights without sacrificing accuracy.

+

INT4 AWQ (Activation-aware Weight Quantization)

+

For the Llama 3 family, we use AWQ to compress weights to 4 bits. This reduces model size by ~75%, allowing larger models to fit into L4 GPU memory and significantly improving token generation speed.

+

FP8 precision

+

For NVIDIA Hopper (H100) architectures, we are exploring FP8 quantization, leveraging native FP8 tensor cores to accelerate matrix multiplications while maintaining a higher dynamic range than integer quantization.

+
    +
  • Verification: We validate quantized models by comparing dot-product similarity of embeddings against the FP16 baseline, consistently achieving >99% similarity.
  • +
+

3. Kernel Fusion & Custom Plugins

+

To minimize overhead from launching thousands of small GPU operations, we fuse them into monolithic kernels using NVIDIA TensorRT plugins.

+
    +
  • Flash attention & FMHA: We enable Fused Multi-Head Attention (FMHA) combined with flash attention to reduce memory reads/writes.
  • +
  • GEMM plugins: We use specialized GEMM plugins to accelerate transformer linear layers.
  • +
  • Removing input padding: Instead of padding short sequences to match the longest, we remove input padding so the GPU processes only valid tokens.
  • +
+

4. Inflight (Continuous) Batching

+

Traditional static batching waits for all requests in a batch to finish before returning results—so one long response delays everyone else.

+

We implement inflight batching: as soon as one request completes, its slot is freed and filled by a new request from the queue. This keeps GPUs saturated and decouples latency of short queries from long ones.

+

5. Parallelism Strategies: Scaling Beyond One GPU

+

For large models (e.g., 70B+ parameters) that cannot fit into the VRAM of a single GPU, we use parallelism strategies.

+
    +
  • Tensor parallelism (TP): Split weight matrices across multiple GPUs (e.g., 4× L4 or 8× A100). Each GPU computes a shard and outputs are reduced at every layer.
  • +
  • Pipeline parallelism (PP): Split model layers across GPUs to pipeline compute (e.g., while one GPU computes later layers for Request A, another starts early layers for Request B).
  • +
+

6. Speculative Decoding

+

To reduce inter-token latency (ITL), we explore speculative decoding.

+
    +
  • Mechanism: A smaller, faster "draft" model speculatively generates a short token sequence (e.g., 5 tokens).
  • +
  • Verification: The larger target model verifies those tokens in one parallel forward pass. If correct, we effectively generate multiple tokens per large-model step; if not, we discard and regenerate. This is effective for predictable text, improving perceived generation speed.
  • +
+

Few Benchmarks

+

Below are a couple of representative use cases and performance numbers.

+

Search query rewriting

+
    +
  • LLM: Fine-tuned llama-3.2-1B
  • +
  • Input & output token length: ~10–20
  • +
  • Response type: Non-streaming
  • +
+
Inference runtimeHardwareMax requests/secMax p99 latency
TensorRT-LLM4 × L4 GPUs (multi-GPU)100095 ms
TensorRT-LLM1 × A100 40 GB GPU100069 ms
+

Voice bot query

+
    +
  • LLM: Llama-3.1-8B
  • +
  • Input token length: ~1900–2000
  • +
  • Output token length: ~200
  • +
  • Response type: Streaming
  • +
+
Inference runtimeConcurrencyp99 TTFT (ms)p99 ITL (ms)Token throughput (tokens/sec)Request throughput (req/sec)Hardware
TensorRT-LLM136.2722.7845.660.23L4
TensorRT-LLM249.8123.2189.370.45L4
TensorRT-LLM455.3336.62153.390.78L4
TensorRT-LLM866.539.11279.881.47L4
TensorRT-LLM16131.830.39547.82.77L4
TensorRT-LLM32277.2248.02925.74.78L4
TensorRT-LLM64498.5271.621,164.406.2L4
TensorRT-LLM128677.31120.371,445.187.69L4
TensorRT-LLM2561,926.31216.881,600.818.52L4
TensorRT-LLM121.179.24130.050.68A100
TensorRT-LLM225.789.21264.51.35A100
TensorRT-LLM428.5210.99437.692.27A100
TensorRT-LLM834.412.61760.493.96A100
TensorRT-LLM1668.0314.321,343.807.01A100
TensorRT-LLM32185.9616.822,287.3011.92A100
TensorRT-LLM64136.8721.173,625.2218.89A100
TensorRT-LLM128463.7834.154,456.5123.24A100
TensorRT-LLM256890.1259.185,188.2427.05A100
+

Conclusion

+

High-performance LLM inference is fundamentally a systems engineering problem: memory efficiency, kernel execution, batching strategy, and parallelism determine real-world latency and throughput. Techniques such as paged KV caching, aggressive quantization, kernel fusion, and inflight batching improve GPU utilization while reducing latency and memory pressure.

+

These optimizations enable the platform to deliver sub-second responses, sustain high concurrency, and efficiently serve both lightweight and long-context workloads. By continuously optimizing across the full inference stack, we keep LLM serving scalable, cost-efficient, and production-ready for real-time AI applications.

Cracking the Code: Scaling Model Inference & Real-Time Embedding Search

· 4 min read
Aditya Kumar
Lead Software Engineer @ Meesho
Jaya Kumar
Lead ML Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+ +

By mid-2023, we had transformed our ML stack—building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:

+
    +
  • 🔹 Scaling model inference without hitting infrastructure roadblocks
  • +
  • 🔹 Moving embedding search from batch to real-time for candidate generation
  • +
+

Here’s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system.

+

Breaking Free from the Scalability Ceiling

+

The Model Serving Bottleneck—A Wake-Up Call

+

July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue—scaling our model-serving infrastructure was taking 10–15 minutes. In real-time ML, that’s an eternity. +In one of our war rooms, we ran a quick experiment:

+
    +
  • 🚀 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine.
  • +
  • 🚀 Fired requests and compared the outputs with our existing cloud-hosted setup.
  • +
  • 🚀 The results matched—perfectly.
  • +
+

That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn't allocate enough compute resources in time. Luckily, they did—but the seed was planted. +Then in October, just two weeks before MBS, we got an alarming response from our infrastructure team: +"Node availability may be an issue." +With no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?

+
    +
  • ✅ p99 latency dropped from 90–100ms to 30–40ms
  • +
  • ✅ Triton handled significantly higher throughput on fewer resources
  • +
  • ✅ No model changes were needed
  • +
+

MBS ran without a hitch, proving that self-hosted inference was the way forward.

+

Scaling Triton on GKE

+

This left us with two choices:

+
    +
  • 1️⃣ Port models to a managed cloud inference service, investing time in learning a new deployment stack
  • +
  • 2️⃣ Scale our existing Triton setup on GKE, optimizing for cost and performance
  • +
+

We went with Option 2—and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations.

+

Fixing the Cold Start Problem

+

As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7–9 minutes to spin up.

+

After profiling, we found the culprits:

+
    +
  • Triton’s base image—a massive 5GB
  • +
  • Model binaries—often 1GB+
  • +
  • Startup delay—mostly due to downloading and initializing these assets
  • +
+

To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother.

+

Embedding Search: The Last Piece of the Puzzle

+

By mid-2023, most of our ML stack had gone real-time—except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system.

+

Choosing the Right Vector Database

+

We benchmarked three production-ready vector DBs across key parameters:

+
    +
  • Milvus
  • +
  • Qdrant
  • +
  • Weaviate
  • +
+

After extensive POCs, Qdrant stood out for its:

+
    +
  • ✅ Blazing-fast search latency on high-dimensional vectors
  • +
  • ✅ Efficient memory usage, crucial for in-memory workloads
  • +
  • ✅ Support for upserts and soft deletes, vital for Ads use cases
  • +
  • ✅ gRPC + REST APIs, making integration seamless
  • +
  • ✅ Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)
  • +
+

At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search—a perfect fit for our needs.

+

Embedding Freshness & Real-Time Updates

+

To ensure embeddings stayed up to date, we built a dual ingestion pipeline:

+
    +
  • 📌 Daily Refresh: A bulk pipeline updated embeddings overnight
  • +
  • 📌 Real-Time Updates: Ads events triggered immediate upserts/deletes
  • +
+

This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.

+

Skye

+

Final Takeaways: Scaling Smartly for Real-Time ML

+
    +
  • 🚀 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services
  • +
  • 🚀 Building a custom Triton image reduced cold starts, improving responsiveness
  • +
  • 🚀 Qdrant-based embedding search enabled real-time personalization at scale
  • +
  • 🚀 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations
  • +
+

By early 2024, Meesho’s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead.

Cracking the Code: Scaling Model Inference & Real-Time Embedding Search

· 4 min read
Aditya Kumar
Lead Software Engineer @ Meesho
Jaya Kumar
Lead ML Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+ +

By mid-2023, we had transformed our ML stack—building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:

+
    +
  • 🔹 Scaling model inference without hitting infrastructure roadblocks
  • +
  • 🔹 Moving embedding search from batch to real-time for candidate generation
  • +
+

Here’s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system.

+

Breaking Free from the Scalability Ceiling

+

The Model Serving Bottleneck—A Wake-Up Call

+

July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue—scaling our model-serving infrastructure was taking 10–15 minutes. In real-time ML, that’s an eternity. +In one of our war rooms, we ran a quick experiment:

+
    +
  • 🚀 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine.
  • +
  • 🚀 Fired requests and compared the outputs with our existing cloud-hosted setup.
  • +
  • 🚀 The results matched—perfectly.
  • +
+

That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn't allocate enough compute resources in time. Luckily, they did—but the seed was planted. +Then in October, just two weeks before MBS, we got an alarming response from our infrastructure team: +"Node availability may be an issue." +With no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?

+
    +
  • ✅ p99 latency dropped from 90–100ms to 30–40ms
  • +
  • ✅ Triton handled significantly higher throughput on fewer resources
  • +
  • ✅ No model changes were needed
  • +
+

MBS ran without a hitch, proving that self-hosted inference was the way forward.

+

Scaling Triton on GKE

+

This left us with two choices:

+
    +
  • 1️⃣ Port models to a managed cloud inference service, investing time in learning a new deployment stack
  • +
  • 2️⃣ Scale our existing Triton setup on GKE, optimizing for cost and performance
  • +
+

We went with Option 2—and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations.

+

Fixing the Cold Start Problem

+

As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7–9 minutes to spin up.

+

After profiling, we found the culprits:

+
    +
  • Triton’s base image—a massive 5GB
  • +
  • Model binaries—often 1GB+
  • +
  • Startup delay—mostly due to downloading and initializing these assets
  • +
+

To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother.

+

Embedding Search: The Last Piece of the Puzzle

+

By mid-2023, most of our ML stack had gone real-time—except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system.

+

Choosing the Right Vector Database

+

We benchmarked three production-ready vector DBs across key parameters:

+
    +
  • Milvus
  • +
  • Qdrant
  • +
  • Weaviate
  • +
+

After extensive POCs, Qdrant stood out for its:

+
    +
  • ✅ Blazing-fast search latency on high-dimensional vectors
  • +
  • ✅ Efficient memory usage, crucial for in-memory workloads
  • +
  • ✅ Support for upserts and soft deletes, vital for Ads use cases
  • +
  • ✅ gRPC + REST APIs, making integration seamless
  • +
  • ✅ Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)
  • +
+

At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search—a perfect fit for our needs.

+

Embedding Freshness & Real-Time Updates

+

To ensure embeddings stayed up to date, we built a dual ingestion pipeline:

+
    +
  • 📌 Daily Refresh: A bulk pipeline updated embeddings overnight
  • +
  • 📌 Real-Time Updates: Ads events triggered immediate upserts/deletes
  • +
+

This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.

+

Skye

+

Final Takeaways: Scaling Smartly for Real-Time ML

+
    +
  • 🚀 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services
  • +
  • 🚀 Building a custom Triton image reduced cold starts, improving responsiveness
  • +
  • 🚀 Qdrant-based embedding search enabled real-time personalization at scale
  • +
  • 🚀 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations
  • +
+

By early 2024, Meesho’s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead.

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

· 7 min read
Bhawani Singh
Architect @ Meesho
Jigar Dave
Lead Software Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+

Building Meesho’s ML Platform: Lessons from the First-Gen System (Part 2)

+

By late 2022, we had built something we were truly proud of—a real-time ML serving system with a DAG-based executor, a feature store, and an interaction store powering key ranking and personalization models. It was a major milestone, the culmination of months of effort from data scientists, ML engineers, and backend teams. Our system was live, and we were ready to push the boundaries of experimentation. +And it worked. Mostly. +But soon, cracks appeared. Every new model needed custom feature retrieval logic, DAGs became dense and unmanageable, and scaling turned into a constant firefight. Costs surged, and infra bottlenecks slowed experimentation. Our system worked, but it wasn’t built for scale. +This is the story of how we tackled these challenges—building Inferflow for seamless feature retrieval, optimizing real-time infra, and cutting costs while scaling to millions of QPS.

+

The Cost of Success

+

Every new Ranker model required its own feature set, often pulling from different entities. Each addition meant:

+
    +
  • Adding new DAG nodes in IOP
  • +
  • Writing custom logic to fetch features from multiple sources (e.g., user, product, user × category)
  • +
  • Inferring intermediate features (e.g., extracting category from a product to fetch user × category data)
  • +
  • Optimizing I/O and dealing with the inevitable bugs
  • +
+

What began as clean DAGs soon turned into a tangled web of cross-dependent graphs. Every experimentation cycle meant new nodes, new dependencies, and slower iterations.

+

Scaling Pains (and Cassandra’s Limits)

+

At some point, we were hitting:

+
    +
  • 250–300K reads/sec
  • +
  • 1M writes/sec (during lean hours)
  • +
+

All of this ran on Cassandra. While its distributed architecture had been proven in production, operating large-scale clusters came with considerable infrastructure overhead. Our proof-of-concept (POC) demonstrated throughput of around 100K ops/sec, but as we scaled further, the challenges grew. Ensuring node health, optimizing compaction, and maintaining storage balance became increasingly demanding. We also observed latency spikes under heavy load, alongside a sharp increase in total cost of ownership.

+

Interaction Store Woes

+

Our interaction store was another ticking time bomb:

+
    +
  • 🚨 Clusters kept growing in size and cost
  • +
  • 🚨 Latency spikes became increasingly frequent
  • +
  • 🚨 The DMC proxy occasionally lost locality of nodes against shards, causing cross-node communication and degraded performance
  • +
+

Each time this happened, we had to manually rebalance shards just to restore stable latency, making operations unsustainable at scale.

+

Silver Linings

+

Despite the chaos, the system was live and delivering value:

+
    +
  • Real-time infrastructure was in production
  • +
  • Costs dropped by 60–70% compared to offline personalization
  • +
  • New experiments rolled out faster and more successfully
  • +
  • User engagement metrics improved
  • +
+

It wasn’t perfect. It was far from easy. But it worked—and that counted for a lot.

+

Round Two: Solving the Top 2 Bottlenecks

+

With the first-gen system stretched to its limits, we stepped back. Conversations with data scientists and backend engineers revealed three recurring pain points:

+
    +
  1. Coding feature retrieval logic for every new model was becoming unsustainable
  2. +
  3. ML scale was exploding—bringing rising infra costs with it
  4. +
  5. Real-time embedding search was the next big unlock
  6. +
+

We tackled them one by one—starting with the biggest pain point.

+

Problem 1: No-Code Feature Retrieval for Model Inference

+

We noticed a pattern: for personalized ranking, models needed features from:

+
    +
  • ✅ Product
  • +
  • ✅ User
  • +
  • ✅ User × Category
  • +
  • ✅ Region, cohort, sub-category, etc.
  • +
+

A key insight emerged: Entities that contribute features for a model always map back to the context entities.

+

MP Dag

+

With this, we designed Inferflow, a graph-driven feature retrieval and model orchestration system:

+
    +
  • 1️⃣ Inferflow takes a modelId and context IDs (e.g., userId, productIds)
  • +
  • 2️⃣ Loads a pre-defined feature retrieval graph from ZooKeeper
  • +
  • 3️⃣ Executes the graph to resolve entity relationships dynamically
  • +
  • 4️⃣ Outputs a 2D matrix of feature vectors
  • +
+

💡 The impact?

+
    +
  • 🚀 No more custom feature retrieval code—just graph updates in config
  • +
  • 🚀 Feature consistency across experiments
  • +
  • 🚀 Faster iteration cycles for ranking, fraud detection, and beyond
  • +
+

Here’s a visual example that shows how this graph plays out during execution. We further extended the graph to call multiple models as needed: +MP matrix +We built Inferflow in GoLang, using gRPC and Proto3 serialization for efficiency.

+

Problem 2: Scaling Without Breaking the Bank

+

With more ML use cases coming online, we needed to cut costs without compromising performance. We focused on:

+
    +
  • 🔹 Online Feature Store
  • +
  • 🔹 Interaction Store
  • +
+

Optimizing the Online Feature Store

+

Our costs were concentrated in:

+
    +
  • 📌 Database (Cassandra)
  • +
  • 📌 Cache (Redis)
  • +
  • 📌 Running Pods (Java services)
  • +
+

1️⃣ Replacing Cassandra with ScyllaDB +As we hit the operational limits of large Cassandra clusters, we transitioned to ScyllaDB, which offered a seamless drop-in replacement without major code changes. The switch brought significant benefits:

+
    +
  • Throughput: Matched or exceeded Cassandra's performance under identical workloads, even under high concurrency.
  • +
  • Latency: Achieved consistently lower P99 latencies due to ScyllaDB's shard-per-core architecture and better I/O utilization.
  • +
  • Cost Efficiency: Reduced infra footprint by ~70% through better CPU and memory efficiency, eliminating the need for over-provisioned nodes.
  • +
+

2️⃣ Finding the Right Cache +To reduce backend load and improve response times, we benchmarked multiple caching solutions—Memcached, KeyDB, and Dragonfly—under real production traffic patterns. Dragonfly stood out due to its robust architecture and operational simplicity:

+
    +
  • Data Skew Handling: Efficiently managed extreme key hotness and uneven access patterns without performance degradation.
  • +
  • Throughput: Delivered consistently high throughput, even with large object sizes and concurrent access.
  • +
  • Ease of Adoption: Acted as a drop-in Redis replacement with full protocol compatibility—no changes needed in application code or client libraries.
  • +
+

3️⃣ Moving to GoLang for Cost-Efficient Serving +Java services were memory-heavy—so we rewrote core services in GoLang. The results?

+

✅ Memory usage dropped by ~80% +✅ CPU utilization was significantly lower +✅ Faster, more efficient deployments

+

Optimizing the Interaction Store

+

We realized that we only need a user’s interaction data in Redis when they open the app. So, we implemented a tiered storage approach:

+
    +
  • 📌 Cold Tier (ScyllaDB)—Stores click, order, wishlist events
  • +
  • 📌 Hot Tier (Redis)—Loads a user’s past interactions only when they open the app
  • +
+

Smart Offloading: We introduced an inactivity tracker to detect when a user session ends. At that point, Redis data was flushed back to Scylla, reducing unnecessary writes.

+

InteractionStore

+

Results

+
    +
  • Online Feature Store hit 1M QPS for the first time during the 2023 Mega Blockbuster Sale—without breaking a sweat
  • +
  • Infra costs for Online Feature Store and Interaction Store dropped by ~60%
  • +
+

The Catch: Our ML Hosting Hit a Hard Limit

+

While planning for 2023 MBS, we ran into a critical scalability bottleneck:

+
    +
  • ❌ Insufficient compute availability in our region for ML instances
  • +
  • ❌ Couldn’t provision enough nodes to handle real-time inference at scale
  • +
+

This forced us to rethink where and how we hosted our models. The existing setup was great for prototyping—but it wasn’t built to handle the bursty, high-QPS demands of real-world production workloads.

+

Conclusion: From Firefighting to Future-Proofing

+

What started as an ambitious experiment turned into a real-time ML infrastructure that powered millions of requests per second. We battled scaling pains, rethought feature retrieval with Inferflow, and rebuilt our infra stack for efficiency—driving down costs while improving experimentation velocity. +But new challenges emerged. Our infrastructure could now handle scale, but our ML model hosting setup hit a hard limit. With compute availability bottlenecks threatening real-time inference, we faced a critical decision: how do we make model serving as scalable and cost-efficient as the rest of our stack? That’s the next piece of the puzzle—and the story of Part 3.

Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1)

· 11 min read
Adarsha Das
Senior Architect @ Meesho
Aditya Kumar
Lead Software Engineer @ Meesho
Bhawani Singh
Architect @ Meesho
Jigar Dave
Lead Software Engineer @ Meesho

BharatMLStack

The Genesis: How a Friday Night Roast Sparked Meesho’s ML Platform

It all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting—until one remark hit a little too close to home:

"Why are we still crunching data for Monthly Active Users (MAU) when the next day it’s all about Daily Active Users (DAU)?"

@@ -204,6 +547,6 @@

+

This foundational work laid the path for a reliable and scalable real-time feature serving layer.

\ No newline at end of file diff --git a/docs/blog/tags/model-inference/index.html b/docs/blog/tags/model-inference/index.html new file mode 100644 index 00000000..a630ecd7 --- /dev/null +++ b/docs/blog/tags/model-inference/index.html @@ -0,0 +1,93 @@ + + + + + +One post tagged with "model-inference" | BharatMLStack + + + + + + + + +

One post tagged with "model-inference"

View All Tags

Cracking the Code: Scaling Model Inference & Real-Time Embedding Search

· 4 min read
Aditya Kumar
Lead Software Engineer @ Meesho
Jaya Kumar
Lead ML Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+ +

By mid-2023, we had transformed our ML stack—building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:

+
    +
  • 🔹 Scaling model inference without hitting infrastructure roadblocks
  • +
  • 🔹 Moving embedding search from batch to real-time for candidate generation
  • +
+

Here’s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system.

+

Breaking Free from the Scalability Ceiling

+

The Model Serving Bottleneck—A Wake-Up Call

+

July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue—scaling our model-serving infrastructure was taking 10–15 minutes. In real-time ML, that’s an eternity. +In one of our war rooms, we ran a quick experiment:

+
    +
  • 🚀 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine.
  • +
  • 🚀 Fired requests and compared the outputs with our existing cloud-hosted setup.
  • +
  • 🚀 The results matched—perfectly.
  • +
+

That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn't allocate enough compute resources in time. Luckily, they did—but the seed was planted. +Then in October, just two weeks before MBS, we got an alarming response from our infrastructure team: +"Node availability may be an issue." +With no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?

+
    +
  • ✅ p99 latency dropped from 90–100ms to 30–40ms
  • +
  • ✅ Triton handled significantly higher throughput on fewer resources
  • +
  • ✅ No model changes were needed
  • +
+

MBS ran without a hitch, proving that self-hosted inference was the way forward.

+

Scaling Triton on GKE

+

This left us with two choices:

+
    +
  • 1️⃣ Port models to a managed cloud inference service, investing time in learning a new deployment stack
  • +
  • 2️⃣ Scale our existing Triton setup on GKE, optimizing for cost and performance
  • +
+

We went with Option 2—and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations.

+

Fixing the Cold Start Problem

+

As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7–9 minutes to spin up.

+

After profiling, we found the culprits:

+
    +
  • Triton’s base image—a massive 5GB
  • +
  • Model binaries—often 1GB+
  • +
  • Startup delay—mostly due to downloading and initializing these assets
  • +
+

To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother.

+

Embedding Search: The Last Piece of the Puzzle

+

By mid-2023, most of our ML stack had gone real-time—except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system.

+

Choosing the Right Vector Database

+

We benchmarked three production-ready vector DBs across key parameters:

+
    +
  • Milvus
  • +
  • Qdrant
  • +
  • Weaviate
  • +
+

After extensive POCs, Qdrant stood out for its:

+
    +
  • ✅ Blazing-fast search latency on high-dimensional vectors
  • +
  • ✅ Efficient memory usage, crucial for in-memory workloads
  • +
  • ✅ Support for upserts and soft deletes, vital for Ads use cases
  • +
  • ✅ gRPC + REST APIs, making integration seamless
  • +
  • ✅ Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)
  • +
+

At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search—a perfect fit for our needs.

+

Embedding Freshness & Real-Time Updates

+

To ensure embeddings stayed up to date, we built a dual ingestion pipeline:

+
    +
  • 📌 Daily Refresh: A bulk pipeline updated embeddings overnight
  • +
  • 📌 Real-Time Updates: Ads events triggered immediate upserts/deletes
  • +
+

This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.

+

Skye

+

Final Takeaways: Scaling Smartly for Real-Time ML

+
    +
  • 🚀 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services
  • +
  • 🚀 Building a custom Triton image reduced cold starts, improving responsiveness
  • +
  • 🚀 Qdrant-based embedding search enabled real-time personalization at scale
  • +
  • 🚀 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations
  • +
+

By early 2024, Meesho’s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead.

+ + \ No newline at end of file diff --git a/docs/blog/tags/online-feature-store/index.html b/docs/blog/tags/online-feature-store/index.html index 6ae561ea..dc3c003b 100644 --- a/docs/blog/tags/online-feature-store/index.html +++ b/docs/blog/tags/online-feature-store/index.html @@ -4,15 +4,15 @@ One post tagged with "online-feature-store" | BharatMLStack - - - + + + -

One post tagged with "online-feature-store"

View All Tags

Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1)

· 11 min read
Adarsha Das
Senior Architect @ Meesho
Aditya Kumar
SDE-III @ Meesho
Bhawani Singh
SDE-IV @ Meesho
Jigar Dave
SDE-IV @ Meesho

BharatMLStack

+

One post tagged with "online-feature-store"

View All Tags

Building Meesho’s ML Platform: From Chaos to Cutting-Edge (Part 1)

· 11 min read
Adarsha Das
Senior Architect @ Meesho
Aditya Kumar
Lead Software Engineer @ Meesho
Bhawani Singh
Architect @ Meesho
Jigar Dave
Lead Software Engineer @ Meesho

BharatMLStack

The Genesis: How a Friday Night Roast Sparked Meesho’s ML Platform

It all started in early 2022, over a casual Friday evening catch-up. Like many great origin stories, this one began with friendly banter between a group of backend engineers and data scientists. As the conversations unfolded, so did the roasting—until one remark hit a little too close to home:

"Why are we still crunching data for Monthly Active Users (MAU) when the next day it’s all about Daily Active Users (DAU)?"

@@ -204,6 +204,6 @@

+

This foundational work laid the path for a reliable and scalable real-time feature serving layer.

\ No newline at end of file diff --git a/docs/blog/tags/tensorrt-llm/index.html b/docs/blog/tags/tensorrt-llm/index.html new file mode 100644 index 00000000..f614cf7f --- /dev/null +++ b/docs/blog/tags/tensorrt-llm/index.html @@ -0,0 +1,157 @@ + + + + + +2 posts tagged with "tensorrt-llm" | BharatMLStack + + + + + + + + +

2 posts tagged with "tensorrt-llm"

View All Tags

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

· 5 min read
Jaya Kumar
Lead ML Engineer @ Meesho

BharatMLStack

+

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

+

Raw execution of Large Language Models is inherently expensive and memory-intensive. To achieve sub-second latency and high throughput, we implement a multi-layered optimization strategy that targets the entire inference stack—from memory management to kernel execution.

+

1. Advanced Memory Management: Paged & Prefix KV Caching

+

The most significant bottleneck in LLM inference is not always compute, but memory bandwidth—specifically managing the Key-Value (KV) cache.

+

Paged KV caching

+

Standard caching suffers from fragmentation. We use Paged KV caching, which operates similarly to an operating system's virtual memory: the KV cache is divided into non-contiguous blocks. This lets us serve larger batch sizes without running out of memory.

+

KV cache quantization

+

To further maximize available memory, we implement KV cache quantization (e.g., FP8). By compressing stored attention keys and values from 16-bit to 8-bit, we nearly double the effective context window capacity of the GPU, allowing longer conversations or larger batches without materially degrading quality.

+

Prefix caching (the "voice bot" optimizer)

+

For use cases like GenAI voice bots where the system prompt (e.g., "You are a helpful assistant...") is static across thousands of requests, we enable prefix caching.

+
    +
  • Impact: By reusing pre-computed KV states for common prefixes, we achieve a cache hit rate of ~90%. This reduces Time To First Token (TTFT) by skipping redundant computation of the system prompt.
  • +
+

2. Aggressive Quantization (INT4 AWQ & FP8)

+

Running models in their native 16-bit precision (BF16) restricts maximum batch size and throughput. We use quantization to shrink model weights without sacrificing accuracy.

+

INT4 AWQ (Activation-aware Weight Quantization)

+

For the Llama 3 family, we use AWQ to compress weights to 4 bits. This reduces model size by ~75%, allowing larger models to fit into L4 GPU memory and significantly improving token generation speed.

+

FP8 precision

+

For NVIDIA Hopper (H100) architectures, we are exploring FP8 quantization, leveraging native FP8 tensor cores to accelerate matrix multiplications while maintaining a higher dynamic range than integer quantization.

+
    +
  • Verification: We validate quantized models by comparing dot-product similarity of embeddings against the FP16 baseline, consistently achieving >99% similarity.
  • +
+

3. Kernel Fusion & Custom Plugins

+

To minimize overhead from launching thousands of small GPU operations, we fuse them into monolithic kernels using NVIDIA TensorRT plugins.

+
    +
  • Flash attention & FMHA: We enable Fused Multi-Head Attention (FMHA) combined with flash attention to reduce memory reads/writes.
  • +
  • GEMM plugins: We use specialized GEMM plugins to accelerate transformer linear layers.
  • +
  • Removing input padding: Instead of padding short sequences to match the longest, we remove input padding so the GPU processes only valid tokens.
  • +
+

4. Inflight (Continuous) Batching

+

Traditional static batching waits for all requests in a batch to finish before returning results—so one long response delays everyone else.

+

We implement inflight batching: as soon as one request completes, its slot is freed and filled by a new request from the queue. This keeps GPUs saturated and decouples latency of short queries from long ones.

+

5. Parallelism Strategies: Scaling Beyond One GPU

+

For large models (e.g., 70B+ parameters) that cannot fit into the VRAM of a single GPU, we use parallelism strategies.

+
    +
  • Tensor parallelism (TP): Split weight matrices across multiple GPUs (e.g., 4× L4 or 8× A100). Each GPU computes a shard and outputs are reduced at every layer.
  • +
  • Pipeline parallelism (PP): Split model layers across GPUs to pipeline compute (e.g., while one GPU computes later layers for Request A, another starts early layers for Request B).
  • +
+

6. Speculative Decoding

+

To reduce inter-token latency (ITL), we explore speculative decoding.

+
    +
  • Mechanism: A smaller, faster "draft" model speculatively generates a short token sequence (e.g., 5 tokens).
  • +
  • Verification: The larger target model verifies those tokens in one parallel forward pass. If correct, we effectively generate multiple tokens per large-model step; if not, we discard and regenerate. This is effective for predictable text, improving perceived generation speed.
  • +
+

Few Benchmarks

+

Below are a couple of representative use cases and performance numbers.

+

Search query rewriting

+
    +
  • LLM: Fine-tuned llama-3.2-1B
  • +
  • Input & output token length: ~10–20
  • +
  • Response type: Non-streaming
  • +
+
Inference runtimeHardwareMax requests/secMax p99 latency
TensorRT-LLM4 × L4 GPUs (multi-GPU)100095 ms
TensorRT-LLM1 × A100 40 GB GPU100069 ms
+

Voice bot query

+
    +
  • LLM: Llama-3.1-8B
  • +
  • Input token length: ~1900–2000
  • +
  • Output token length: ~200
  • +
  • Response type: Streaming
  • +
+
Inference runtimeConcurrencyp99 TTFT (ms)p99 ITL (ms)Token throughput (tokens/sec)Request throughput (req/sec)Hardware
TensorRT-LLM136.2722.7845.660.23L4
TensorRT-LLM249.8123.2189.370.45L4
TensorRT-LLM455.3336.62153.390.78L4
TensorRT-LLM866.539.11279.881.47L4
TensorRT-LLM16131.830.39547.82.77L4
TensorRT-LLM32277.2248.02925.74.78L4
TensorRT-LLM64498.5271.621,164.406.2L4
TensorRT-LLM128677.31120.371,445.187.69L4
TensorRT-LLM2561,926.31216.881,600.818.52L4
TensorRT-LLM121.179.24130.050.68A100
TensorRT-LLM225.789.21264.51.35A100
TensorRT-LLM428.5210.99437.692.27A100
TensorRT-LLM834.412.61760.493.96A100
TensorRT-LLM1668.0314.321,343.807.01A100
TensorRT-LLM32185.9616.822,287.3011.92A100
TensorRT-LLM64136.8721.173,625.2218.89A100
TensorRT-LLM128463.7834.154,456.5123.24A100
TensorRT-LLM256890.1259.185,188.2427.05A100
+

Conclusion

+

High-performance LLM inference is fundamentally a systems engineering problem: memory efficiency, kernel execution, batching strategy, and parallelism determine real-world latency and throughput. Techniques such as paged KV caching, aggressive quantization, kernel fusion, and inflight batching improve GPU utilization while reducing latency and memory pressure.

+

These optimizations enable the platform to deliver sub-second responses, sustain high concurrency, and efficiently serve both lightweight and long-context workloads. By continuously optimizing across the full inference stack, we keep LLM serving scalable, cost-efficient, and production-ready for real-time AI applications.

Cracking the Code: Scaling Model Inference & Real-Time Embedding Search

· 4 min read
Aditya Kumar
Lead Software Engineer @ Meesho
Jaya Kumar
Lead ML Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+ +

By mid-2023, we had transformed our ML stack—building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:

+
    +
  • 🔹 Scaling model inference without hitting infrastructure roadblocks
  • +
  • 🔹 Moving embedding search from batch to real-time for candidate generation
  • +
+

Here’s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system.

+

Breaking Free from the Scalability Ceiling

+

The Model Serving Bottleneck—A Wake-Up Call

+

July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue—scaling our model-serving infrastructure was taking 10–15 minutes. In real-time ML, that’s an eternity. +In one of our war rooms, we ran a quick experiment:

+
    +
  • 🚀 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine.
  • +
  • 🚀 Fired requests and compared the outputs with our existing cloud-hosted setup.
  • +
  • 🚀 The results matched—perfectly.
  • +
+

That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn't allocate enough compute resources in time. Luckily, they did—but the seed was planted. +Then in October, just two weeks before MBS, we got an alarming response from our infrastructure team: +"Node availability may be an issue." +With no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?

+
    +
  • ✅ p99 latency dropped from 90–100ms to 30–40ms
  • +
  • ✅ Triton handled significantly higher throughput on fewer resources
  • +
  • ✅ No model changes were needed
  • +
+

MBS ran without a hitch, proving that self-hosted inference was the way forward.

+

Scaling Triton on GKE

+

This left us with two choices:

+
    +
  • 1️⃣ Port models to a managed cloud inference service, investing time in learning a new deployment stack
  • +
  • 2️⃣ Scale our existing Triton setup on GKE, optimizing for cost and performance
  • +
+

We went with Option 2—and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations.

+

Fixing the Cold Start Problem

+

As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7–9 minutes to spin up.

+

After profiling, we found the culprits:

+
    +
  • Triton’s base image—a massive 5GB
  • +
  • Model binaries—often 1GB+
  • +
  • Startup delay—mostly due to downloading and initializing these assets
  • +
+

To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother.

+

Embedding Search: The Last Piece of the Puzzle

+

By mid-2023, most of our ML stack had gone real-time—except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system.

+

Choosing the Right Vector Database

+

We benchmarked three production-ready vector DBs across key parameters:

+
    +
  • Milvus
  • +
  • Qdrant
  • +
  • Weaviate
  • +
+

After extensive POCs, Qdrant stood out for its:

+
    +
  • ✅ Blazing-fast search latency on high-dimensional vectors
  • +
  • ✅ Efficient memory usage, crucial for in-memory workloads
  • +
  • ✅ Support for upserts and soft deletes, vital for Ads use cases
  • +
  • ✅ gRPC + REST APIs, making integration seamless
  • +
  • ✅ Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)
  • +
+

At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search—a perfect fit for our needs.

+

Embedding Freshness & Real-Time Updates

+

To ensure embeddings stayed up to date, we built a dual ingestion pipeline:

+
    +
  • 📌 Daily Refresh: A bulk pipeline updated embeddings overnight
  • +
  • 📌 Real-Time Updates: Ads events triggered immediate upserts/deletes
  • +
+

This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.

+

Skye

+

Final Takeaways: Scaling Smartly for Real-Time ML

+
    +
  • 🚀 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services
  • +
  • 🚀 Building a custom Triton image reduced cold starts, improving responsiveness
  • +
  • 🚀 Qdrant-based embedding search enabled real-time personalization at scale
  • +
  • 🚀 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations
  • +
+

By early 2024, Meesho’s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead.

+ + \ No newline at end of file diff --git a/docs/blog/tags/vllm/index.html b/docs/blog/tags/vllm/index.html new file mode 100644 index 00000000..c5ce9278 --- /dev/null +++ b/docs/blog/tags/vllm/index.html @@ -0,0 +1,157 @@ + + + + + +2 posts tagged with "vllm" | BharatMLStack + + + + + + + + +

2 posts tagged with "vllm"

View All Tags

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

· 5 min read
Jaya Kumar
Lead ML Engineer @ Meesho

BharatMLStack

+

LLM Inference Optimization Techniques: Engineering Sub-Second Latency at Scale

+

Raw execution of Large Language Models is inherently expensive and memory-intensive. To achieve sub-second latency and high throughput, we implement a multi-layered optimization strategy that targets the entire inference stack—from memory management to kernel execution.

+

1. Advanced Memory Management: Paged & Prefix KV Caching

+

The most significant bottleneck in LLM inference is not always compute, but memory bandwidth—specifically managing the Key-Value (KV) cache.

+

Paged KV caching

+

Standard caching suffers from fragmentation. We use Paged KV caching, which operates similarly to an operating system's virtual memory: the KV cache is divided into non-contiguous blocks. This lets us serve larger batch sizes without running out of memory.

+

KV cache quantization

+

To further maximize available memory, we implement KV cache quantization (e.g., FP8). By compressing stored attention keys and values from 16-bit to 8-bit, we nearly double the effective context window capacity of the GPU, allowing longer conversations or larger batches without materially degrading quality.

+

Prefix caching (the "voice bot" optimizer)

+

For use cases like GenAI voice bots where the system prompt (e.g., "You are a helpful assistant...") is static across thousands of requests, we enable prefix caching.

+
    +
  • Impact: By reusing pre-computed KV states for common prefixes, we achieve a cache hit rate of ~90%. This reduces Time To First Token (TTFT) by skipping redundant computation of the system prompt.
  • +
+

2. Aggressive Quantization (INT4 AWQ & FP8)

+

Running models in their native 16-bit precision (BF16) restricts maximum batch size and throughput. We use quantization to shrink model weights without sacrificing accuracy.

+

INT4 AWQ (Activation-aware Weight Quantization)

+

For the Llama 3 family, we use AWQ to compress weights to 4 bits. This reduces model size by ~75%, allowing larger models to fit into L4 GPU memory and significantly improving token generation speed.

+

FP8 precision

+

For NVIDIA Hopper (H100) architectures, we are exploring FP8 quantization, leveraging native FP8 tensor cores to accelerate matrix multiplications while maintaining a higher dynamic range than integer quantization.

+
    +
  • Verification: We validate quantized models by comparing dot-product similarity of embeddings against the FP16 baseline, consistently achieving >99% similarity.
  • +
+

3. Kernel Fusion & Custom Plugins

+

To minimize overhead from launching thousands of small GPU operations, we fuse them into monolithic kernels using NVIDIA TensorRT plugins.

+
    +
  • Flash attention & FMHA: We enable Fused Multi-Head Attention (FMHA) combined with flash attention to reduce memory reads/writes.
  • +
  • GEMM plugins: We use specialized GEMM plugins to accelerate transformer linear layers.
  • +
  • Removing input padding: Instead of padding short sequences to match the longest, we remove input padding so the GPU processes only valid tokens.
  • +
+

4. Inflight (Continuous) Batching

+

Traditional static batching waits for all requests in a batch to finish before returning results—so one long response delays everyone else.

+

We implement inflight batching: as soon as one request completes, its slot is freed and filled by a new request from the queue. This keeps GPUs saturated and decouples latency of short queries from long ones.

+

5. Parallelism Strategies: Scaling Beyond One GPU

+

For large models (e.g., 70B+ parameters) that cannot fit into the VRAM of a single GPU, we use parallelism strategies.

+
    +
  • Tensor parallelism (TP): Split weight matrices across multiple GPUs (e.g., 4× L4 or 8× A100). Each GPU computes a shard and outputs are reduced at every layer.
  • +
  • Pipeline parallelism (PP): Split model layers across GPUs to pipeline compute (e.g., while one GPU computes later layers for Request A, another starts early layers for Request B).
  • +
+

6. Speculative Decoding

+

To reduce inter-token latency (ITL), we explore speculative decoding.

+
    +
  • Mechanism: A smaller, faster "draft" model speculatively generates a short token sequence (e.g., 5 tokens).
  • +
  • Verification: The larger target model verifies those tokens in one parallel forward pass. If correct, we effectively generate multiple tokens per large-model step; if not, we discard and regenerate. This is effective for predictable text, improving perceived generation speed.
  • +
+

Few Benchmarks

+

Below are a couple of representative use cases and performance numbers.

+

Search query rewriting

+
    +
  • LLM: Fine-tuned llama-3.2-1B
  • +
  • Input & output token length: ~10–20
  • +
  • Response type: Non-streaming
  • +
+
Inference runtimeHardwareMax requests/secMax p99 latency
TensorRT-LLM4 × L4 GPUs (multi-GPU)100095 ms
TensorRT-LLM1 × A100 40 GB GPU100069 ms
+

Voice bot query

+
    +
  • LLM: Llama-3.1-8B
  • +
  • Input token length: ~1900–2000
  • +
  • Output token length: ~200
  • +
  • Response type: Streaming
  • +
+
Inference runtimeConcurrencyp99 TTFT (ms)p99 ITL (ms)Token throughput (tokens/sec)Request throughput (req/sec)Hardware
TensorRT-LLM136.2722.7845.660.23L4
TensorRT-LLM249.8123.2189.370.45L4
TensorRT-LLM455.3336.62153.390.78L4
TensorRT-LLM866.539.11279.881.47L4
TensorRT-LLM16131.830.39547.82.77L4
TensorRT-LLM32277.2248.02925.74.78L4
TensorRT-LLM64498.5271.621,164.406.2L4
TensorRT-LLM128677.31120.371,445.187.69L4
TensorRT-LLM2561,926.31216.881,600.818.52L4
TensorRT-LLM121.179.24130.050.68A100
TensorRT-LLM225.789.21264.51.35A100
TensorRT-LLM428.5210.99437.692.27A100
TensorRT-LLM834.412.61760.493.96A100
TensorRT-LLM1668.0314.321,343.807.01A100
TensorRT-LLM32185.9616.822,287.3011.92A100
TensorRT-LLM64136.8721.173,625.2218.89A100
TensorRT-LLM128463.7834.154,456.5123.24A100
TensorRT-LLM256890.1259.185,188.2427.05A100
+

Conclusion

+

High-performance LLM inference is fundamentally a systems engineering problem: memory efficiency, kernel execution, batching strategy, and parallelism determine real-world latency and throughput. Techniques such as paged KV caching, aggressive quantization, kernel fusion, and inflight batching improve GPU utilization while reducing latency and memory pressure.

+

These optimizations enable the platform to deliver sub-second responses, sustain high concurrency, and efficiently serve both lightweight and long-context workloads. By continuously optimizing across the full inference stack, we keep LLM serving scalable, cost-efficient, and production-ready for real-time AI applications.

Cracking the Code: Scaling Model Inference & Real-Time Embedding Search

· 4 min read
Aditya Kumar
Lead Software Engineer @ Meesho
Jaya Kumar
Lead ML Engineer @ Meesho
Adarsha Das
Senior Architect @ Meesho

BharatMLStack

+ +

By mid-2023, we had transformed our ML stack—building a real-time feature store, optimizing model retrieval, and fine-tuning ranking. But two critical gaps remained:

+
    +
  • 🔹 Scaling model inference without hitting infrastructure roadblocks
  • +
  • 🔹 Moving embedding search from batch to real-time for candidate generation
  • +
+

Here’s how we tackled these last-mile challenges, broke free from infrastructure constraints, and built a cost-efficient, high-performance system.

+

Breaking Free from the Scalability Ceiling

+

The Model Serving Bottleneck—A Wake-Up Call

+

July 2023. With just months left for the Mega Blockbuster Sale (MBS), we noticed a serious issue—scaling our model-serving infrastructure was taking 10–15 minutes. In real-time ML, that’s an eternity. +In one of our war rooms, we ran a quick experiment:

+
    +
  • 🚀 We deployed an XGBoost model on a self-hosted Triton Inference Server running on a 16-core machine.
  • +
  • 🚀 Fired requests and compared the outputs with our existing cloud-hosted setup.
  • +
  • 🚀 The results matched—perfectly.
  • +
+

That moment changed everything. We prepped a backup Triton setup on EKS, just in case our cloud provider couldn't allocate enough compute resources in time. Luckily, they did—but the seed was planted. +Then in October, just two weeks before MBS, we got an alarming response from our infrastructure team: +"Node availability may be an issue." +With no time to waste, we moved 30% of real-time ML traffic to our self-hosted Triton cluster. The results?

+
    +
  • ✅ p99 latency dropped from 90–100ms to 30–40ms
  • +
  • ✅ Triton handled significantly higher throughput on fewer resources
  • +
  • ✅ No model changes were needed
  • +
+

MBS ran without a hitch, proving that self-hosted inference was the way forward.

+

Scaling Triton on GKE

+

This left us with two choices:

+
    +
  • 1️⃣ Port models to a managed cloud inference service, investing time in learning a new deployment stack
  • +
  • 2️⃣ Scale our existing Triton setup on GKE, optimizing for cost and performance
  • +
+

We went with Option 2—and it slashed inference costs to 35% of what we previously paid, while giving us full control over scaling and optimizations.

+

Fixing the Cold Start Problem

+

As we onboarded more deep learning (DL) models, we hit a new bottleneck, new inference pods took 7–9 minutes to spin up.

+

After profiling, we found the culprits:

+
    +
  • Triton’s base image—a massive 5GB
  • +
  • Model binaries—often 1GB+
  • +
  • Startup delay—mostly due to downloading and initializing these assets
  • +
+

To fix this, we built a lightweight Triton image, stripping unused components and shrinking the size to 900MB. This cut cold start times drastically, making auto-scaling faster and smoother.

+

Embedding Search: The Last Piece of the Puzzle

+

By mid-2023, most of our ML stack had gone real-time—except for Candidate Generation (CG), which still ran in batch mode. To truly power real-time recommendations, we needed an online embedding search system.

+

Choosing the Right Vector Database

+

We benchmarked three production-ready vector DBs across key parameters:

+
    +
  • Milvus
  • +
  • Qdrant
  • +
  • Weaviate
  • +
+

After extensive POCs, Qdrant stood out for its:

+
    +
  • ✅ Blazing-fast search latency on high-dimensional vectors
  • +
  • ✅ Efficient memory usage, crucial for in-memory workloads
  • +
  • ✅ Support for upserts and soft deletes, vital for Ads use cases
  • +
  • ✅ gRPC + REST APIs, making integration seamless
  • +
  • ✅ Powerful filtering, allowing fine-tuned retrieval (e.g., filtering Ads by category, active status, etc.)
  • +
+

At its core, Qdrant uses HNSW indexing, delivering both high recall and low-latency nearest-neighbor search—a perfect fit for our needs.

+

Embedding Freshness & Real-Time Updates

+

To ensure embeddings stayed up to date, we built a dual ingestion pipeline:

+
    +
  • 📌 Daily Refresh: A bulk pipeline updated embeddings overnight
  • +
  • 📌 Real-Time Updates: Ads events triggered immediate upserts/deletes
  • +
+

This setup powered real-time "Similar Products" recommendations on the product page and became the foundation for Ads Candidate Generation, ensuring the right ads surfaced in milliseconds.

+

Skye

+

Final Takeaways: Scaling Smartly for Real-Time ML

+
    +
  • 🚀 Self-hosted inference on Triton gave us lower cost, faster scaling, and better performance than managed services
  • +
  • 🚀 Building a custom Triton image reduced cold starts, improving responsiveness
  • +
  • 🚀 Qdrant-based embedding search enabled real-time personalization at scale
  • +
  • 🚀 Real-time updates for embeddings unlocked dynamic, up-to-date recommendations
  • +
+

By early 2024, Meesho’s ML stack had evolved into a fully real-time, scalable, and cost-efficient system, setting the foundation for even bigger leaps ahead.

+ + \ No newline at end of file diff --git a/docs/category/go-sdk/index.html b/docs/category/go-sdk/index.html index 8e58e52a..56e2e431 100644 --- a/docs/category/go-sdk/index.html +++ b/docs/category/go-sdk/index.html @@ -4,14 +4,14 @@ Go SDK | BharatMLStack - - - + + + -

Go SDK

Go SDK for BharatML Stack. Provides Go client libraries and packages for interacting with the online feature store, including gRPC clients and protocol buffer definitions.

+

Go SDK

Go SDK for BharatML Stack. Provides Go client libraries and packages for interacting with the online feature store, including gRPC clients and protocol buffer definitions.

\ No newline at end of file diff --git a/docs/category/inferflow/index.html b/docs/category/inferflow/index.html new file mode 100644 index 00000000..054fa36f --- /dev/null +++ b/docs/category/inferflow/index.html @@ -0,0 +1,17 @@ + + + + + +Inferflow | BharatMLStack + + + + + + + + +

Inferflow

Inferflow is a graph-driven feature retrieval and model inference orchestration engine. It dynamically resolves entity relationships via configurable DAGs, retrieves features from the Online Feature Store, and orchestrates model scoring — all without custom code.

+ + \ No newline at end of file diff --git a/docs/category/numerix/index.html b/docs/category/numerix/index.html new file mode 100644 index 00000000..c4b73d39 --- /dev/null +++ b/docs/category/numerix/index.html @@ -0,0 +1,17 @@ + + + + + +Numerix | BharatMLStack + + + + + + + + +

Numerix

Numerix is a mathematical compute engine for BharatML Stack. It is used to perform mathematical operations on matrices and vectors.

+ + \ No newline at end of file diff --git a/docs/category/online-feature-store/index.html b/docs/category/online-feature-store/index.html index 8b52edc4..75ca8c79 100644 --- a/docs/category/online-feature-store/index.html +++ b/docs/category/online-feature-store/index.html @@ -4,14 +4,14 @@ Online Feature Store | BharatMLStack - - - + + + -

Online Feature Store

Online-feature-store is a high-performance, scalable, and production-grade feature store built for modern machine learning systems. It supports both real-time and batch workflows, with a strong emphasis on developer experience, system observability, and low-latency feature retrieval.

+

Online Feature Store

Online-feature-store is a high-performance, scalable, and production-grade feature store built for modern machine learning systems. It supports both real-time and batch workflows, with a strong emphasis on developer experience, system observability, and low-latency feature retrieval.

\ No newline at end of file diff --git a/docs/category/python-sdk/index.html b/docs/category/python-sdk/index.html index 4d4ac5de..cdea2a59 100644 --- a/docs/category/python-sdk/index.html +++ b/docs/category/python-sdk/index.html @@ -4,14 +4,14 @@ Python SDK | BharatMLStack - - - + + + -

Python SDK

Python SDK for BharatML Stack. Provides Python client libraries and utilities for interacting with the online feature store, including gRPC clients, Spark integration, and common utilities.

+

Python SDK

Python SDK for BharatML Stack. Provides Python client libraries and utilities for interacting with the online feature store, including gRPC clients, Spark integration, and common utilities.

\ No newline at end of file diff --git a/docs/category/quick-start/index.html b/docs/category/quick-start/index.html index 9e6dc2d1..a04bd2a8 100644 --- a/docs/category/quick-start/index.html +++ b/docs/category/quick-start/index.html @@ -4,14 +4,14 @@ Quick Start | BharatMLStack - - - + + + -

Quick Start

Quick Start guide for BharatML Stack. Get up and running quickly with step-by-step instructions, sample data, and Docker Compose setup for local development and testing.

+

Quick Start

Quick Start guide for BharatML Stack. Get up and running quickly with step-by-step instructions, sample data, and Docker Compose setup for local development and testing.

\ No newline at end of file diff --git a/docs/category/sdks/index.html b/docs/category/sdks/index.html index f6c91986..d9e7c141 100644 --- a/docs/category/sdks/index.html +++ b/docs/category/sdks/index.html @@ -4,14 +4,14 @@ SDKs | BharatMLStack - - - + + + -

SDKs

Software Development Kits (SDKs) for BharatML Stack. Includes client libraries for Go and Python to interact with the online feature store and other platform components.

+

SDKs

Software Development Kits (SDKs) for BharatML Stack. Includes client libraries for Go and Python to interact with the online feature store and other platform components.

\ No newline at end of file diff --git a/docs/category/trufflebox-ui/index.html b/docs/category/trufflebox-ui/index.html index be9543fc..192feb18 100644 --- a/docs/category/trufflebox-ui/index.html +++ b/docs/category/trufflebox-ui/index.html @@ -4,14 +4,14 @@ Trufflebox UI | BharatMLStack - - - + + + -

Trufflebox UI

Trufflebox UI is a modern, feature rich UI framework for supporting MLOps. It supports Feature catalog, management, user managemnet and other adminops

+

Trufflebox UI

Trufflebox UI is a modern, feature rich UI framework for supporting MLOps. It supports Feature catalog, management, user managemnet and other adminops

\ No newline at end of file diff --git a/docs/category/v100/index.html b/docs/category/v100/index.html index f3681e85..65f65f90 100644 --- a/docs/category/v100/index.html +++ b/docs/category/v100/index.html @@ -3,15 +3,15 @@ -v1.0.0 | BharatMLStack - - - +v1.0.0 | BharatMLStack + + + -

v1.0.0

Python SDK v1.0.0 documentation for BharatML Stack. Contains API reference, usage guides, and examples for the Python client libraries including gRPC feature client, Spark feature push client, and common utilities.

+ \ No newline at end of file diff --git a/docs/img/v1.0.0-inferflow-arch.png b/docs/img/v1.0.0-inferflow-arch.png new file mode 100644 index 00000000..acad4888 Binary files /dev/null and b/docs/img/v1.0.0-inferflow-arch.png differ diff --git a/docs/img/v1.0.0-inferflow-dag-matrix.png b/docs/img/v1.0.0-inferflow-dag-matrix.png new file mode 100644 index 00000000..2345d69f Binary files /dev/null and b/docs/img/v1.0.0-inferflow-dag-matrix.png differ diff --git a/docs/index.html b/docs/index.html index ed910758..4f2a8eb9 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3,15 +3,15 @@ -BharatMLStack - Open Source ML Infrastructure | BharatMLStack - - - +BharatMLStack - Open Source ML Infrastructure | BharatMLStack + + + -
BharatMLStack Logo

Welcome to BharatMLStack

Open source, end-to-end ML infrastructure stack built for scale, speed, and simplicity.

Sub-10msP99 Latency
1M+ RPSTested Capacity
Multi-DBSupport

Online Feature Store

High-performance, production-ready feature serving for real-time ML inference

🚀

High-Performance Feature Store

Sub-10ms P99 latency and 1M+ RPS capacity. Built for real-time ML inference with custom PSDB serialization format that outperforms Protocol Buffers and Apache Arrow.

Production-Ready ML Infrastructure

Multi-database backends (Scylla, Dragonfly, Redis), comprehensive monitoring, and enterprise-grade features. Deploy with confidence using battle-tested components.

🛠️

Developer-First Experience

Multi-language SDKs (Go, Python), gRPC APIs, and extensive documentation. From data scientists, ML engineers to backend engineers, everyone gets tools they love.

Built for India's Scale

BharatMLStack is a comprehensive, production-ready machine learning infrastructure platform designed to democratize ML capabilities across India and beyond. Our mission is to provide a robust, scalable, and accessible ML stack that empowers organizations to build, deploy, and manage machine learning solutions at massive scale.

Explore Online Feature Store →

🏆 Key Achievements

  • ✅ Sub-10ms P99 latency for real-time inference
  • ✅ 1M+ RPS tested with 100 IDs per request
  • ✅ PSDB format outperforms Proto3 & Arrow
  • ✅ Multi-database: Scylla, Dragonfly, Redis
  • ✅ Production-ready with comprehensive monitoring

Trufflebox UI

Modern, feature-rich UI framework for comprehensive MLOps management

📋

Feature Catalog & Management

Comprehensive feature catalog with metadata management, versioning, and governance. Organize and discover features across your ML platform with ease.

👥

User Management & Admin Ops

Role-based access control, user authentication, and administrative operations. Secure your ML platform with enterprise-grade user management capabilities.

🎨

Modern UI Framework

Intuitive, responsive web interface built with modern web technologies. Streamline MLOps workflows with beautiful and functional user experiences.

Modern MLOps Management

Trufflebox UI provides a comprehensive, modern web interface for managing your entire ML infrastructure. Built with cutting-edge web technologies, it delivers an intuitive experience for feature management, user administration, and operational oversight. Streamline your MLOps workflows with enterprise-grade UI components.

Explore Trufflebox UI →

🎨 UI Features

  • ✅ Comprehensive feature catalog & discovery
  • ✅ Role-based access control & user management
  • ✅ Job, Store, Admin Ops management
  • ✅ Approval flow for everything
  • ✅ Responsive design for desktop & mobile

SDKs

Developer-friendly client libraries and APIs for seamless platform integration

🌐

Multi-Language Support

Native SDKs for Go and Python with idiomatic APIs. Choose the language that fits your team's expertise and existing infrastructure.

🔗

gRPC & REST APIs

High-performance gRPC clients and REST APIs for seamless integration. Built-in support for streaming, batching, and async operations.

Spark Integration

Native Apache Spark integration for batch feature processing and ingestion. Scale your feature engineering workflows with distributed computing power.

Developer-First Integration

Our SDKs are designed with developers in mind, providing idiomatic APIs for Go and Python that feel natural in your existing codebase. Whether you're building microservices, data pipelines, or ML applications, our SDKs provide the tools you need for seamless integration with BharatMLStack's powerful infrastructure.

Explore SDKs →

🛠️ Developer Tools

  • ✅ Native Go & Python SDKs with type safety
  • ✅ High-performance gRPC
  • ✅ Apache Spark integration for publishing features
+
BharatMLStack Logo

Welcome to BharatMLStack

Open source, end-to-end ML infrastructure stack built for scale, speed, and simplicity.

Sub-10msP99 Latency
1M+ RPSTested Capacity
Multi-DBSupport

Online Feature Store

High-performance, production-ready feature serving for real-time ML inference

🚀

High-Performance Feature Store

Sub-10ms P99 latency and 1M+ RPS capacity. Built for real-time ML inference with custom PSDB serialization format that outperforms Protocol Buffers and Apache Arrow.

Production-Ready ML Infrastructure

Multi-database backends (Scylla, Dragonfly, Redis), comprehensive monitoring, and enterprise-grade features. Deploy with confidence using battle-tested components.

🛠️

Developer-First Experience

Multi-language SDKs (Go, Python), gRPC APIs, and extensive documentation. From data scientists, ML engineers to backend engineers, everyone gets tools they love.

Built for India's Scale

BharatMLStack is a comprehensive, production-ready machine learning infrastructure platform designed to democratize ML capabilities across India and beyond. Our mission is to provide a robust, scalable, and accessible ML stack that empowers organizations to build, deploy, and manage machine learning solutions at massive scale.

Explore Online Feature Store →

🏆 Key Achievements

  • ✅ Sub-10ms P99 latency for real-time inference
  • ✅ 1M+ RPS tested with 100 IDs per request
  • ✅ PSDB format outperforms Proto3 & Arrow
  • ✅ Multi-database: Scylla, Dragonfly, Redis
  • ✅ Production-ready with comprehensive monitoring

Trufflebox UI

Modern, feature-rich UI framework for comprehensive MLOps management

📋

Feature Catalog & Management

Comprehensive feature catalog with metadata management, versioning, and governance. Organize and discover features across your ML platform with ease.

👥

User Management & Admin Ops

Role-based access control, user authentication, and administrative operations. Secure your ML platform with enterprise-grade user management capabilities.

🎨

Modern UI Framework

Intuitive, responsive web interface built with modern web technologies. Streamline MLOps workflows with beautiful and functional user experiences.

Modern MLOps Management

Trufflebox UI provides a comprehensive, modern web interface for managing your entire ML infrastructure. Built with cutting-edge web technologies, it delivers an intuitive experience for feature management, user administration, and operational oversight. Streamline your MLOps workflows with enterprise-grade UI components.

Explore Trufflebox UI →

🎨 UI Features

  • ✅ Comprehensive feature catalog & discovery
  • ✅ Role-based access control & user management
  • ✅ Job, Store, Admin Ops management
  • ✅ Approval flow for everything
  • ✅ Responsive design for desktop & mobile

SDKs

Developer-friendly client libraries and APIs for seamless platform integration

🌐

Multi-Language Support

Native SDKs for Go and Python with idiomatic APIs. Choose the language that fits your team's expertise and existing infrastructure.

🔗

gRPC & REST APIs

High-performance gRPC clients and REST APIs for seamless integration. Built-in support for streaming, batching, and async operations.

Spark Integration

Native Apache Spark integration for batch feature processing and ingestion. Scale your feature engineering workflows with distributed computing power.

Developer-First Integration

Our SDKs are designed with developers in mind, providing idiomatic APIs for Go and Python that feel natural in your existing codebase. Whether you're building microservices, data pipelines, or ML applications, our SDKs provide the tools you need for seamless integration with BharatMLStack's powerful infrastructure.

Explore SDKs →

🛠️ Developer Tools

  • ✅ Native Go & Python SDKs with type safety
  • ✅ High-performance gRPC
  • ✅ Apache Spark integration for publishing features

Numerix

Numerix is a mathematical compute engine for BharatML Stack. It is used to perform mathematical operations on matrices and vectors.

Explore Numerix →

🛠️ Numerix Features

  • ✅ Postfix expression evaluation
  • ✅ Vectorized math operations
  • ✅ Typed evaluation
  • ✅ Compiler-assisted SIMD
  • ✅ ARM & AMD support
  • ✅ Multi-arch builds
  • ✅ Deterministic runtime
\ No newline at end of file diff --git a/docs/inferflow/v1.0.0/architecture/index.html b/docs/inferflow/v1.0.0/architecture/index.html new file mode 100644 index 00000000..aa0a5091 --- /dev/null +++ b/docs/inferflow/v1.0.0/architecture/index.html @@ -0,0 +1,171 @@ + + + + + +Architecture | BharatMLStack + + + + + + + + +

BharatMLStack - Inferflow

+

Inferflow is part of BharatMLStack, a graph-driven feature retrieval and model inference orchestration engine built in Go. It eliminates the need for custom feature retrieval code by using configurable DAG topologies to dynamically resolve entity relationships, fetch features from the Online Feature Store, and orchestrate model scoring — all driven by configuration stored in etcd.

+
+

Overview

+

In a typical ML serving pipeline, every new model requires bespoke code to:

+
    +
  • Fetch features from multiple entities (user, product, user x category, etc.)
  • +
  • Infer intermediate entity relationships (e.g., extract category from product to fetch user x category data)
  • +
  • Orchestrate one or more model inference calls
  • +
  • Handle I/O, batching, and error propagation
  • +
+

Inferflow abstracts all of this behind a config-driven DAG executor. Given a model_config_id and context entities (e.g., userId, productIds), it:

+
    +
  1. Loads a pre-defined feature retrieval and inference graph from etcd
  2. +
  3. Executes the graph to resolve entity relationships dynamically
  4. +
  5. Retrieves features from the Online Feature Store (OnFS) in parallel
  6. +
  7. Calls model serving endpoints (Predator) and compute services (Numerix)
  8. +
  9. Returns scored results as a structured response
  10. +
+
+

High-Level Architecture

+

Inferflow Architecture - DAG Topology Executor

+

The diagram shows the internal DAG structure of Inferflow's topology executor. gRPC APIs (Pair, Point, Slate) feed into the DAG, where Feature Init bootstraps the ComponentMatrix. Feature components (FS User, FS Product, FS Region, FS User Cat, FS Region Scat) fetch features from OnFS in parallel and populate columns in the shared 2D Result Matrix. Model components (Model A, Model B) call Predator for inference, and compute components call Numerix for operations like reranking. The entire DAG topology is driven by config loaded from etcd.

+
+

Core Components

+

1. gRPC Server

+

Inferflow exposes its APIs via a gRPC server, with HTTP health endpoints multiplexed on the same port using cmux. The server provides:

+
    +
  • Inferflow APIRetrieveModelScore: entity-based feature retrieval and scoring
  • +
  • Predict APIInferPointWise, InferPairWise, InferSlateWise: structured inference with targets, pairs, and slates
  • +
+

2. DAG Topology Executor

+

The heart of Inferflow. Each model configuration defines a component_dependency map that describes a Directed Acyclic Graph (DAG) of components.

+

Execution model:

+
    +
  • Uses Kahn's algorithm for topological ordering
  • +
  • Components at the same level run concurrently in goroutines
  • +
  • All components share a mutable ComponentMatrix (rows = entity IDs, columns = features/scores)
  • +
  • DAG topologies are cached using Murmur3 hashing with Ristretto cache
  • +
+

Validation:

+
    +
  • Cycle detection via in-degree analysis
  • +
  • Component existence verification against the ComponentProvider
  • +
+

3. Component Types

+

Inferflow defines four types of DAG components:

+
ComponentRoleExternal Dependency
FeatureInitComponentRoot node — initializes the ComponentMatrix with entity IDs and schemaNone
FeatureComponentFetches features from the Online Feature Store for a specific entity typeOnFS (gRPC)
PredatorComponentCalls model serving endpoints for inference scoringPredator / Helix (gRPC)
NumerixComponentCalls compute engine for operations like rerankingNumerix (gRPC)
+

4. ComponentMatrix — The 2D Result Matrix

+

The ComponentMatrix is a shared, mutable 2D data structure that flows through the entire DAG. Every component reads from and writes to this matrix, progressively building a complete feature + score row for each entity.

+

DAG Execution &amp; 2D Matrix Flow

+

How the matrix evolves through the DAG

+

The diagram above illustrates the three execution phases and how the 2D matrix grows at each stage:

+

Phase 1 — Feature Retrieval

+

The init node creates an empty matrix with one row per target entity ID. Feature components then execute — first the top-level entities (entity A, entity B) fetch their features from OnFS and populate their columns (shown as colored blocks). Derived entities (entity C, D, E) resolve their keys from the already-populated columns and add more feature columns. At this point the matrix contains all feature data, with each color representing features from a different entity.

+

The right side of the diagram shows the matrix being decomposed — feature columns from different entities are separated into per-model input groups, selecting only the features each model needs.

+

Phase 2 — Model Invocation

+

Model X and Model Y each receive their decomposed feature slices, call Predator for inference, and write score columns back into the matrix (shown as new colored columns appended to the right). Multiple models can run in parallel if they don't depend on each other's outputs.

+

The scores are then decomposed again to prepare inputs for the compute stage.

+

Phase 3 — Numerix Compute

+

The Score Comb node takes score columns from both models, calls Numerix for a final compute operation (e.g., score combination, reranking), and writes the final score column (shown in dark red) into the matrix. The result is a complete row per entity with all features and all scores.

+

Matrix structure

+
PropertyDescription
RowsOne per target entity ID (e.g., each product being scored)
String columnsHuman-readable values used in responses
Byte columnsBinary-encoded feature values used for model inputs
Column namingentity_label:feature_group:feature_name
+

Each component only reads the columns it needs and writes to its own columns, enabling safe concurrent execution across independent branches of the DAG.

+

For slate-based APIs, a companion SlateData structure holds per-slate matrices and scores, with slate_target_indices mapping slates to rows in the main matrix.

+

5. Configuration Management (etcd)

+

Model configurations are stored in etcd and hot-reloaded via watchers:

+
    +
  • Config paths: /config/inferflow/services/, /model-config
  • +
  • Watch mechanism: etcd watchers trigger ReloadModelConfigMapAndRegisterComponents on any change
  • +
  • On reload: Updates ConfigMap, re-initializes feature schemas, and re-registers DAG components
  • +
+

This means new models or configuration changes go live without redeployment.

+

6. External Integrations

+

Online Feature Store (OnFS)

+
    +
  • gRPC client calling FeatureService.RetrieveFeatures
  • +
  • Batched retrieval with configurable batch size and deadline
  • +
  • Auth via CALLER_ID and CALLER_TOKEN metadata
  • +
+

Predator (Model Serving)

+
    +
  • Uses go-sdk for model inference
  • +
  • Supports percentage-based traffic routing across multiple model endpoints
  • +
  • Configurable calibration and batch sizing
  • +
+

Numerix (Compute Engine)

+
    +
  • Uses go-sdk Numerix client
  • +
  • RPC: NumerixService.Compute with entity score data
  • +
  • Used for compute operations like reranking
  • +
+

Kafka (Inference Logging)

+
    +
  • Async inference log publishing using segmentio/kafka-go
  • +
  • Supports Proto, Arrow, and Parquet serialization formats
  • +
  • Configurable sampling via LoggingPerc and user-based daily sampling
  • +
+
+

Request Flow

+
1. Client sends gRPC request with model_config_id + entity IDs

2. Load ModelConfig from etcd-backed ConfigMap

3. Adapt proto request → ComponentRequest
(build ComponentMatrix with entity schema)

4. Resolve DAG topology from component_dependency config

5. Execute DAG (Kahn's algorithm, concurrent):

├─ FeatureInitComponent: populate matrix with entity IDs + schema

├─ FeatureComponents (parallel): fetch features from OnFS → fill matrix columns

├─ PredatorComponent: build feature payloads from matrix → call model → write scores

└─ NumerixComponent: read scores from matrix → call compute → write final scores

6. Build response from matrix columns per ResponseConfig

7. (Optional) Async Kafka logging of inference features and scores

8. Return gRPC response to client
+
+

Observability

+

Metrics (StatsD / Telegraf)

+
MetricDescription
inferflow.retrievemodelscore.request.totalTotal RetrieveModelScore requests
inferflow.retrievemodelscore.latencyEnd-to-end latency
inferflow.retrievemodelscore.batch.sizeBatch size per request
predict.infer.request.totalTotal Predict API requests
predict.infer.latencyPredict API latency
inferflow.component.execution.totalPer-component execution count
inferflow.component.execution.latencyPer-component latency
inferflow.component.execution.errorComponent-level errors
inferflow.component.feature.countFeature count per component
inferflow.external.api.request.totalExternal API call count
inferflow.external.api.latencyExternal API latency
inferflow.component.inmemorycache.request.totalCache hit/miss total
inferflow.component.inmemorycache.missCache misses
inferflow.logging.kafka_sentKafka log messages sent
+

Logging

+
    +
  • Structured JSON logging via zerolog
  • +
  • Configurable log levels
  • +
+
+

Deployment

+

Docker

+

Inferflow ships as a multi-stage Docker image:

+
    +
  • Builder: Go 1.19 Alpine with optional Kafka support (librdkafka)
  • +
  • Runtime: Debian 10 slim
  • +
  • Build command: go build -tags musl -ldflags "-extldflags -static" -o server cmd/${module}/main.go
  • +
+

Supported Environments

+
    +
  • Kubernetes (K8s)
  • +
  • Google Kubernetes Engine (GKE)
  • +
  • Amazon EKS
  • +
+

Configuration

+

All configuration is driven via environment variables (loaded by Viper) and etcd. No config files are required at deployment time.

+
+

Target Users

+
UserRole
Data ScientistsDefine model configs and feature retrieval graphs via config — no code needed
ML EngineersOnboard new models by updating etcd config; manage DAG topologies
Backend DevelopersIntegrate via gRPC SDKs for real-time scoring in application services
Platform EngineersDeploy, scale, and monitor Inferflow clusters
+
+

Benefits

+
    +
  • No-code feature retrieval — new models need only a config change, not custom code
  • +
  • Feature consistency — same graph-driven retrieval ensures identical features across experiments
  • +
  • Faster iteration — experiment with new models in minutes, not days
  • +
  • Concurrent execution — DAG components run in parallel for minimal latency
  • +
  • Hot reloading — model config changes via etcd go live without redeployment
  • +
  • Multi-API support — PointWise, PairWise, and SlateWise inference patterns out of the box
  • +
  • Production-grade — built in Go with gRPC, designed for millions of QPS
  • +
+
+

Contributing

+

We welcome contributions from the community! Please see our Contributing Guide for details on how to get started.

+

Community & Support

+ +

License

+

BharatMLStack is open-source software licensed under the BharatMLStack Business Source License 1.1.

+
+
Built with ❤️ for the ML community from Meesho
+
If you find this useful, ⭐️ the repo — your support means the world to us!
+ + \ No newline at end of file diff --git a/docs/inferflow/v1.0.0/configuration/index.html b/docs/inferflow/v1.0.0/configuration/index.html new file mode 100644 index 00000000..7eb8f4d3 --- /dev/null +++ b/docs/inferflow/v1.0.0/configuration/index.html @@ -0,0 +1,108 @@ + + + + + +Configuration Guide | BharatMLStack + + + + + + + + +

Inferflow - Configuration Guide

+

Inferflow is fully config-driven. All model onboarding, feature retrieval logic, DAG topology, and inference behavior are controlled through configuration stored in etcd — with zero code changes required.

+
+

Configuration Overview

+

Inferflow configuration is organized into two layers:

+
    +
  1. Static config — Environment variables loaded at startup (via Viper)
  2. +
  3. Dynamic config — Model configurations stored in etcd, hot-reloaded on change
  4. +
+
+

Static Configuration (Environment Variables)

+

These are set at deployment time and require a restart to change.

+

Server

+
VariableDescriptionExample
APP_PORTgRPC/HTTP server port50051
APP_ENVEnvironment nameproduction
+

etcd

+
VariableDescriptionExample
ETCD_ENDPOINTSComma-separated etcd endpointsetcd-0:2379,etcd-1:2379
ETCD_DIAL_TIMEOUTConnection timeout5s
+

Online Feature Store (OnFS)

+
VariableDescriptionExample
externalServiceOnFs_hostOnFS gRPC hostonfs-api:50051
externalServiceOnFs_callerIdCaller ID for authinferflow
externalServiceOnFs_callerTokenCaller token for auth<token>
externalServiceOnFs_batchSizeBatch size for feature retrieval100
externalServiceOnFs_deadlineRequest deadline200ms
+

Predator (Model Serving)

+
VariableDescriptionExample
externalServicePredator_defaultDeadlineDefault inference deadline100ms
+

Numerix (Compute Engine)

+
VariableDescriptionExample
numerixClientV1_hostNumerix gRPC hostnumerix:50052
numerixClientV1_deadlineRequest deadline100ms
+

Kafka (Inference Logging)

+
VariableDescriptionExample
KafkaBootstrapServersKafka broker addresseskafka-0:9092,kafka-1:9092
KafkaLoggingTopicTopic for inference logsinferflow-logs
+

Metrics (StatsD / Telegraf)

+
VariableDescriptionExample
TELEGRAF_HOSTStatsD hosttelegraf
TELEGRAF_PORTStatsD port8125
+

In-Memory Cache

+
VariableDescriptionExample
CACHE_SIZE_MBCache size in MB512
CACHE_TYPECache implementationfreecache
+
+

Dynamic Configuration (etcd Model Config)

+

Model configurations are stored in etcd and hot-reloaded. Each model is identified by a model_config_id.

+

Config Structure

+
{
"model_config_id_example": {
"dag_execution_config": {
"component_dependency": {
"feature_initializer": ["fs_user", "fs_product"],
"fs_user": ["ranker_model"],
"fs_product": ["ranker_model"],
"ranker_model": []
}
},
"component_config": {
"feature_component_config": {
"fs_user": { ... },
"fs_product": { ... }
},
"predator_component_config": {
"ranker_model": { ... }
},
"numerix_component_config": {},
"cache_enabled": true,
"cache_version": "v1",
"cache_ttl": 300,
"error_logging_percent": 10
},
"response_config": {
"features": ["ranker_model:score"],
"model_schema_perc": 100,
"logging_perc": 5,
"log_features": ["fs_user:profile:age", "ranker_model:score"],
"log_batch_size": 100
}
}
}
+
+

DAG Execution Config

+

Defines the component dependency graph.

+
{
"component_dependency": {
"<parent_component>": ["<child_1>", "<child_2>"],
"<child_1>": ["<grandchild>"],
"<child_2>": ["<grandchild>"],
"<grandchild>": []
}
}
+

Rules:

+
    +
  • The graph must be a valid DAG (no cycles)
  • +
  • Components with no parents (zero in-degree) execute first
  • +
  • Components with empty dependency arrays [] are leaf nodes
  • +
  • All component names must match registered components in the ComponentConfig
  • +
+
+

Feature Component Config

+

Configures how features are fetched from the Online Feature Store.

+
{
"fs_user": {
"fs_keys": {
"schema": ["user_id"],
"col": "context:user:user_id"
},
"fs_request": {
"entity_label": "user",
"feature_groups": [
{
"label": "demographics",
"feature_labels": ["age", "location", "income_bracket"]
},
{
"label": "behavior",
"feature_labels": ["click_rate", "purchase_freq"]
}
]
},
"fs_flatten_resp_keys": ["user_id"],
"col_name_prefix": "user",
"comp_cache_enabled": true,
"comp_cache_ttl": 600,
"composite_id": false
}
}
+
FieldDescription
fs_keysHow to extract lookup keys from the matrix. schema defines key column names; col references a matrix column
fs_requestOnFS query: entity label + feature groups with specific features
fs_flatten_resp_keysKeys to flatten in response mapping
col_name_prefixPrefix for matrix column names (e.g., user:demographics:age)
comp_cache_enabledEnable in-memory caching for this component
comp_cache_ttlCache TTL in seconds
composite_idWhether entity keys are composite
+
+

Predator Component Config

+

Configures model inference endpoints.

+
{
"ranker_model": {
"model_name": "product_ranker_v3",
"model_endpoint": "predator-ranker:8080",
"model_end_points": {
"predator-ranker-v3:8080": 80,
"predator-ranker-v4:8080": 20
},
"deadline": 100,
"batch_size": 50,
"calibration": {
"enabled": false
},
"inputs": {
"feature_map": {
"user:demographics:age": "INT32",
"user:behavior:click_rate": "FP32",
"product:attributes:category_id": "INT32"
}
},
"outputs": {
"score_columns": ["score", "confidence"]
},
"slate_component": false
}
}
+
FieldDescription
model_nameModel identifier on the serving platform
model_endpointPrimary model serving endpoint
model_end_pointsMultiple endpoints with percentage-based traffic routing
deadlineInference timeout in milliseconds
batch_sizeMax items per inference batch
calibrationScore calibration settings
inputs.feature_mapMap of matrix column → data type for model input
outputs.score_columnsColumn names for model output scores
slate_componentIf true, runs per-slate inference
+
+

Numerix Component Config

+

Configures compute operations (e.g., reranking).

+
{
"reranker": {
"score_column": "final_score",
"data_type": "FP32",
"score_mapping": {
"ranker_model:score": "FP32",
"user:behavior:click_rate": "FP32"
},
"compute_id": "diversity_rerank_v1",
"slate_component": false
}
}
+
FieldDescription
score_columnOutput column name for the computed score
data_typeOutput data type
score_mappingMap of matrix columns to include as compute inputs
compute_idIdentifies the compute operation on Numerix
slate_componentIf true, runs per-slate compute
+
+

Response Config

+

Controls what data is returned to the client and what is logged.

+
{
"features": ["ranker_model:score", "reranker:final_score"],
"model_schema_perc": 100,
"logging_perc": 5,
"log_features": [
"user:demographics:age",
"ranker_model:score",
"reranker:final_score"
],
"log_batch_size": 100
}
+
FieldDescription
featuresMatrix columns to include in the gRPC response
model_schema_percPercentage of requests that include full schema in response
logging_percPercentage of requests to send to Kafka for logging
log_featuresSpecific features to include in log messages
log_batch_sizeBatch size for grouped log messages
+
+

Service-Level Config

+

Global settings that apply across all models.

+
{
"v2_logging_type": "proto",
"compression_enabled": false
}
+
FieldValuesDescription
v2_logging_typeproto, arrow, parquetSerialization format for Kafka inference logs
compression_enabledtrue, falseEnable compression for log messages
+
+

Example: Onboarding a New Model

+

To onboard a new ranking model, update the etcd config:

+

Step 1: Define the feature retrieval graph

+
"component_dependency": {
"feature_initializer": ["fs_user", "fs_product", "fs_user_x_category"],
"fs_product": ["fs_user_x_category"],
"fs_user": ["new_ranker"],
"fs_user_x_category": ["new_ranker"],
"new_ranker": []
}
+

Here fs_user_x_category depends on fs_product because it needs the category ID extracted from the product entity to resolve the user x category key.

+

Step 2: Configure each component (feature groups, model endpoints, etc.)

+

Step 3: Push the config to etcd — Inferflow picks it up automatically via watchers.

+

No code changes. No redeployment. The new model is live.

+
+

Contributing

+

We welcome contributions from the community! Please see our Contributing Guide for details on how to get started.

+

Community & Support

+ +

License

+

BharatMLStack is open-source software licensed under the BharatMLStack Business Source License 1.1.

+
+
Built with ❤️ for the ML community from Meesho
+
If you find this useful, ⭐️ the repo — your support means the world to us!
+ + \ No newline at end of file diff --git a/docs/inferflow/v1.0.0/functionalities/index.html b/docs/inferflow/v1.0.0/functionalities/index.html new file mode 100644 index 00000000..6dc7d775 --- /dev/null +++ b/docs/inferflow/v1.0.0/functionalities/index.html @@ -0,0 +1,210 @@ + + + + + +Key Functionalities | BharatMLStack + + + + + + + + +

Inferflow - Key Functionalities

+

Overview

+

Inferflow is a high-performance, config-driven ML inference orchestration engine built in Go. It provides no-code feature retrieval, DAG-based execution, and multi-pattern model inference — enabling ML teams to onboard new models through configuration changes alone.

+
+

Core Capabilities

+

Graph-Driven Feature Retrieval

+

Inferflow's defining feature is its ability to resolve entity relationships and retrieve features through configurable DAG topologies — no custom code required.

+

How it works:

+
    +
  1. A model_config_id maps to a pre-defined DAG of components
  2. +
  3. Context entity IDs (e.g., userId, productIds) are provided at request time
  4. +
  5. The DAG resolves intermediate entity relationships (e.g., extracting category from product to fetch user x category features)
  6. +
  7. Features are fetched in parallel from the Online Feature Store
  8. +
  9. A 2D feature matrix is assembled and passed to model scoring
  10. +
+

Impact:

+
    +
  • New models require only a config update — no code changes
  • +
  • Feature consistency is guaranteed across experiments
  • +
  • Iteration cycles drop from days to minutes
  • +
+

DAG Topology Executor

+

The execution engine uses Kahn's algorithm for topological ordering with concurrent goroutine execution at each level:

+
component_dependency: {
"feature_initializer": ["fs_user", "fs_product"],
"fs_user": ["ranker"],
"fs_product": ["ranker"],
"ranker": ["reranker"],
"reranker": []
}
+

This config defines:

+
    +
  • feature_initializer runs first (zero in-degree)
  • +
  • fs_user and fs_product run in parallel after init
  • +
  • ranker runs after both feature components complete
  • +
  • reranker runs after the ranker
  • +
+

Key properties:

+
    +
  • Cycle detection via in-degree analysis
  • +
  • DAG topologies cached using Murmur3 hashing (Ristretto cache)
  • +
  • Components are registered and resolved via a ComponentProvider
  • +
+
+

Multi-Pattern Inference APIs

+

Inferflow supports three inference patterns via the Predict API, each designed for different ML use cases:

+

PointWise Inference

+

Score each target independently against context features.

+
rpc InferPointWise(PredictRequest) returns (PredictResponse);
+

Use cases: Click-through rate prediction, fraud scoring, relevance ranking

+

Input: Context features + list of targets (e.g., products) +Output: Per-target scores

+

PairWise Inference

+

Score pairs of targets relative to each other.

+
rpc InferPairWise(PredictRequest) returns (PredictResponse);
+

Use cases: Preference learning, comparison-based ranking

+

Input: Context features + targets + pair indices (first/second) +Output: Per-pair scores + optional per-target scores

+

SlateWise Inference

+

Score groups (slates) of targets together, capturing inter-item effects.

+
rpc InferSlateWise(PredictRequest) returns (PredictResponse);
+

Use cases: Whole-page optimization, slate-level reranking, diversity-aware scoring

+

Input: Context features + targets + slate definitions (target indices per slate) +Output: Per-slate scores + optional per-target scores

+
+

Entity & Legacy API

+

RetrieveModelScore

+

The original Inferflow API for entity-based feature retrieval and scoring:

+
service Inferflow {
rpc RetrieveModelScore(InferflowRequestProto) returns (InferflowResponseProto);
}
+

Request structure:

+
FieldDescription
entitiesList of entity types with their IDs and optional inline features
model_config_idIdentifies the model configuration (DAG, components, response format)
tracking_idRequest-level tracing identifier
+

Entity structure:

+
    +
  • entity: Entity type label (e.g., "user", "product")
  • +
  • ids: List of entity IDs
  • +
  • features: Optional inline features (name + per-ID values)
  • +
+
+

Component Types

+

FeatureInitComponent

+

Role: Root DAG node — initializes the shared ComponentMatrix.

+
    +
  • Sets up rows from entity IDs
  • +
  • Populates schema columns (string + byte) for all downstream components
  • +
  • For slate APIs: initializes SlateData with slate_target_indices
  • +
+

FeatureComponent

+

Role: Fetches features from the Online Feature Store (OnFS) for a specific entity type.

+
    +
  • Reads FSKeys from config to extract lookup keys from the matrix
  • +
  • Batches unique entities and calls OnFS via gRPC
  • +
  • Optional in-memory caching keyed by model_id:version:component:entity
  • +
  • Writes binary feature values into matrix byte columns
  • +
+

Column naming convention: entity_label:feature_group:feature_name

+

PredatorComponent

+

Role: Calls model serving endpoints for inference.

+
    +
  • Builds feature payloads from matrix columns with type conversion
  • +
  • Supports percentage-based traffic routing across multiple model endpoints
  • +
  • Handles slate-level inference: per-slate matrix → separate inference → scores to SlateData
  • +
  • Configurable calibration and batch sizing
  • +
+

NumerixComponent

+

Role: Calls the Numerix compute engine for operations like reranking.

+
    +
  • Uses ScoreMapping config to map matrix columns to compute inputs
  • +
  • Writes a single score column back to the matrix
  • +
  • Supports slate mode for per-slate compute operations
  • +
+
+

Feature Retrieval Pipeline

+

Key Resolution

+

Feature components use FSKeys configuration to dynamically resolve entity keys:

+
{
"FSKeys": {
"schema": ["user_id"],
"col": "user:profile:user_id"
}
}
+

The component reads key values from the existing matrix columns, enabling chained entity resolution — e.g., fetch product entity first, extract category, then fetch user x category features.

+

Batched Retrieval

+
    +
  • Features are fetched via FeatureService.RetrieveFeatures gRPC call
  • +
  • Requests are batched by unique entity keys
  • +
  • Configurable batch size and deadline per component
  • +
  • Auth via CALLER_ID and CALLER_TOKEN metadata
  • +
+

In-Memory Caching

+

Optional per-component caching reduces OnFS load:

+
    +
  • Cache key: model_id:cache_version:component_name:entity_key
  • +
  • Configurable TTL per component
  • +
  • Zero-GC-overhead cache implementation available
  • +
  • Cache hit/miss metrics tracked via StatsD
  • +
+
+

Data Types

+

Inferflow supports comprehensive ML data types for feature encoding and model input/output:

+
Data TypeVariantsUsage
Integersint8, int16, int32, int64Categorical encodings, counts, IDs
Floatsfloat8 (e4m3, e5m2), float16, float32, float64Continuous features, embeddings, scores
StringsVariable lengthCategories, metadata
BooleansBit-packedBinary indicators
VectorsAll scalar typesEmbeddings, feature arrays
+

Type conversion is handled by the datatypeconverter package with optimized float8 implementations.

+
+

Inference Logging

+

Inferflow supports async inference logging to Kafka for model monitoring and debugging:

+

Serialization Formats

+
FormatUse Case
ProtoDefault, compact
ArrowColumnar analytics
ParquetLong-term storage, query-friendly
+

Sampling Controls

+
ConfigDescription
LoggingPercPercentage of requests to log (0-100)
LogBatchSizeBatch size for log message grouping
LogFeaturesSpecific features to include in logs
+

Log Content

+

Each InferflowLog message includes:

+
    +
  • user_id, tracking_id, model_config_id
  • +
  • Entity IDs and feature values
  • +
  • Model scores and metadata
  • +
+
+

Configuration Hot-Reload

+

Model configurations are stored in etcd and support live updates without redeployment:

+
    +
  1. Inferflow registers watchers on etcd config paths
  2. +
  3. On config change, watchers trigger ReloadModelConfigMapAndRegisterComponents
  4. +
  5. ConfigMap is updated in memory
  6. +
  7. Feature schemas are re-initialized
  8. +
  9. DAG components are re-registered
  10. +
+

This enables:

+
    +
  • Adding new models in production without restarts
  • +
  • A/B testing with different model configurations
  • +
  • Instant rollback by reverting etcd config
  • +
+
+

Performance Characteristics

+

Concurrency Model

+
    +
  • DAG components at the same level execute concurrently in goroutines
  • +
  • Feature retrieval is parallelized across entity types
  • +
  • External gRPC calls use connection pooling
  • +
+

Memory Efficiency

+
    +
  • Built in Go — significantly lower memory footprint than Java equivalents (~80% reduction)
  • +
  • Object pooling for ComponentMatrix and serialization buffers
  • +
  • In-memory cache with zero-GC-overhead option (freecache)
  • +
+

Serialization

+
    +
  • gRPC with Proto3 for all external communication
  • +
  • Binary feature encoding in the ComponentMatrix for minimal overhead
  • +
  • Configurable compression for Kafka logging
  • +
+
+

Contributing

+

We welcome contributions from the community! Please see our Contributing Guide for details on how to get started.

+

Community & Support

+ +

License

+

BharatMLStack is open-source software licensed under the BharatMLStack Business Source License 1.1.

+
+
Built with ❤️ for the ML community from Meesho
+
If you find this useful, ⭐️ the repo — your support means the world to us!
+ + \ No newline at end of file diff --git a/docs/inferflow/v1.0.0/index.html b/docs/inferflow/v1.0.0/index.html new file mode 100644 index 00000000..63bf06cd --- /dev/null +++ b/docs/inferflow/v1.0.0/index.html @@ -0,0 +1,17 @@ + + + + + +v1.0.0 | BharatMLStack + + + + + + + + + + + \ No newline at end of file diff --git a/docs/inferflow/v1.0.0/release-notes/index.html b/docs/inferflow/v1.0.0/release-notes/index.html new file mode 100644 index 00000000..21c42146 --- /dev/null +++ b/docs/inferflow/v1.0.0/release-notes/index.html @@ -0,0 +1,160 @@ + + + + + +Release Notes | BharatMLStack + + + + + + + + +

Inferflow - Release Notes

+

Version 1.0.0

+

Release Date: June 2025 +Status: General Availability (GA)

+

We're excited to announce the first stable release of Inferflow — a graph-driven feature retrieval and model inference orchestration engine, part of BharatMLStack.

+
+

What's New

+

Config-Driven DAG Executor

+
    +
  • No-code feature retrieval: Onboard new models with config changes only — no custom code required
  • +
  • DAG topology execution: Define component dependency graphs that are executed concurrently using Kahn's algorithm
  • +
  • Hot reload: Model configurations stored in etcd are watched and reloaded live — no redeployment needed
  • +
  • DAG caching: Topologies are cached using Murmur3 hashing with Ristretto for minimal overhead
  • +
+

Multi-Pattern Inference APIs

+

Three structured inference patterns via the Predict API:

+
APIPatternUse Case
InferPointWiseScore each target independentlyCTR prediction, fraud scoring
InferPairWiseScore pairs of targetsPreference learning, comparison ranking
InferSlateWiseScore groups of targets togetherWhole-page optimization, diversity-aware ranking
+

Plus the entity-based RetrieveModelScore API for direct feature retrieval and scoring.

+

Component System

+

Four built-in component types:

+
    +
  • FeatureInitComponent — Initializes the shared ComponentMatrix
  • +
  • FeatureComponent — Fetches features from the Online Feature Store (OnFS)
  • +
  • PredatorComponent — Calls model serving endpoints with percentage-based traffic routing
  • +
  • NumerixComponent — Calls compute engine for operations like reranking
  • +
+

Online Feature Store Integration

+
    +
  • gRPC-based feature retrieval via FeatureService.RetrieveFeatures
  • +
  • Batched retrieval with configurable batch size and deadline
  • +
  • Token-based authentication
  • +
  • Dynamic key resolution from the ComponentMatrix
  • +
+

In-Memory Feature Caching

+
    +
  • Optional per-component caching to reduce OnFS load
  • +
  • Configurable TTL per component
  • +
  • Zero-GC-overhead cache option (freecache)
  • +
  • Cache hit/miss metrics
  • +
+

Inference Logging

+
    +
  • Async logging to Kafka for model monitoring and debugging
  • +
  • Three serialization formats: Proto, Arrow, Parquet
  • +
  • Configurable sampling rate and feature selection
  • +
  • Batched log message grouping
  • +
+
+

Performance

+

Built in Go

+

Inferflow is written entirely in Go, delivering:

+
    +
  • ~80% lower memory usage compared to equivalent Java services
  • +
  • Lower CPU utilization
  • +
  • Faster, more efficient deployments
  • +
+

Concurrency

+
    +
  • DAG components at the same level execute concurrently in goroutines
  • +
  • Feature retrieval parallelized across entity types
  • +
  • Connection pooling for all external gRPC calls
  • +
+

Serialization

+
    +
  • gRPC with Proto3 for all APIs
  • +
  • Binary feature encoding in the ComponentMatrix
  • +
  • Configurable compression for Kafka logging (ZSTD support)
  • +
+
+

APIs & Protocols

+

gRPC API

+

Inferflow Service:

+
service Inferflow {
rpc RetrieveModelScore(InferflowRequestProto) returns (InferflowResponseProto);
}
+

Predict Service:

+
service PredictService {
rpc InferPointWise(PredictRequest) returns (PredictResponse);
rpc InferPairWise(PredictRequest) returns (PredictResponse);
rpc InferSlateWise(PredictRequest) returns (PredictResponse);
}
+

Data Types Supported

+
TypeVariants
Integersint8, int16, int32, int64
Floatsfloat8 (e4m3, e5m2), float16, float32, float64
StringsVariable length
BooleansBit-packed
VectorsAll scalar types
+
+

Enterprise Features

+

Production Readiness

+
    +
  • Health checks: HTTP health endpoints via cmux
  • +
  • Graceful shutdown: Clean resource cleanup
  • +
  • Structured logging: JSON-formatted logs via zerolog
  • +
  • Signal handling: SIGTERM/SIGINT support for container environments
  • +
+

Monitoring & Observability

+
    +
  • StatsD / Telegraf integration: Request rates, latencies, error rates
  • +
  • Per-component metrics: Execution time, feature counts, cache hit rates
  • +
  • External API metrics: OnFS, Predator, Numerix call tracking
  • +
  • Kafka logging metrics: Messages sent, errors
  • +
+

Configuration Management

+
    +
  • etcd-based: All model configs stored in etcd
  • +
  • Watch & reload: Live config updates without restart
  • +
  • Multi-model support: Multiple model_config_id entries served concurrently
  • +
+
+

Deployment

+

Container Support

+
    +
  • Docker image: Multi-stage build (Go Alpine builder + Debian runtime)
  • +
  • Optional Kafka: librdkafka support via build flag
  • +
  • Static binary: Single binary deployment
  • +
+

Supported Environments

+
    +
  • Kubernetes (K8s)
  • +
  • Google Kubernetes Engine (GKE)
  • +
  • Amazon EKS
  • +
+
+

Compatibility

+

Supported Go Versions

+
    +
  • Minimum: Go 1.19
  • +
  • Recommended: Go 1.24+
  • +
+

External Dependencies

+
ServiceVersionProtocol
etcd3.5+gRPC
Online Feature Store (OnFS)1.0+gRPC
Predator (Helix)1.0+gRPC
Numerix1.0+gRPC
Kafka2.0+TCP
+
+

Download & Installation

+

Source Code

+
git clone https://github.com/Meesho/BharatMLStack.git
cd BharatMLStack/inferflow
+

Build

+
go build -o inferflow-server cmd/inferflow/main.go
+

Docker

+
docker build -t inferflow:latest .
+
+

Contributing

+

We welcome contributions from the community! Please see our Contributing Guide for details on how to get started.

+

Community & Support

+ +

License

+

BharatMLStack is open-source software licensed under the BharatMLStack Business Source License 1.1.

+
+
Built with ❤️ for the ML community from Meesho
+
If you find this useful, ⭐️ the repo — your support means the world to us!
+ + \ No newline at end of file diff --git a/docs/markdown-page/index.html b/docs/markdown-page/index.html index 70020cdd..cf005ac0 100644 --- a/docs/markdown-page/index.html +++ b/docs/markdown-page/index.html @@ -4,15 +4,15 @@ Markdown page example | BharatMLStack - - - + + +

Markdown page example

-

You don't need React to write simple standalone pages.

+

You don't need React to write simple standalone pages.

\ No newline at end of file diff --git a/docs/numerix/v1.0.0/architecture/index.html b/docs/numerix/v1.0.0/architecture/index.html new file mode 100644 index 00000000..51bb28c8 --- /dev/null +++ b/docs/numerix/v1.0.0/architecture/index.html @@ -0,0 +1,143 @@ + + + + + +Architecture | BharatMLStack + + + + + + + + +

BharatMLStack - Numerix

+
+

Numerix is a Rust-based compute service in BharatMLStack designed for low-latency evaluation of mathematical expressions over feature matrices. Each request carries a compute_id and a matrix of features; Numerix fetches the corresponding postfix expression, maps variables to feature columns (treated as vectors), and evaluates the expression with a stack-based SIMD-optimized runtime.

+
+

High-Level Components

+
    +
  • Tonic gRPC server (Rust): exposes Numerix/Compute for low-latency requests. +
      +
    • Accepts feature data as strings (for ease of use) or byte arrays (for efficient transmission).
    • +
    • All input data is converted internally to fp32 or fp64 vectors for evaluation.
    • +
    +
  • +
  • Compute Registry (etcd): stores compute_id (int) → postfix expression mappings.
  • +
  • Stack-based Evaluator: Runs postfix expressions in linear time using a stack based approach over aligned vectors.
  • +
  • Vectorized Math Runtime: No handwritten SIMD intrinsics; relies on LLVM autovectorization. +
      +
    • Operations are intentionally simple and memory-aligned.
    • +
    • Compiler emits SIMD instructions automatically.
    • +
    • Portable across CPU architectures (ARM & AMD).
    • +
    +
  • +
  • Metrics and Health +
      +
    • Latency, RPS, and error rates via Datadog/DogStatsD UDP client.
    • +
    • Minimal HTTP endpoints (/health, optional /metrics) for diagnostics.
    • +
    +
  • +
+
+

What is SIMD?

+

SIMD (Single Instruction, Multiple Data) is a CPU feature that allows a single instruction to operate on multiple data points at once. In Numerix, this means that operations on feature vectors can be executed in parallel, making evaluation of mathematical expressions faster and more predictable.

+

Why SIMD Matters for Numerix

+
    +
  • Postfix expressions operate on vectors (columns of the input matrix).
  • +
  • SIMD allows multiple elements of these vectors to be processed in one CPU instruction, rather than element-by-element.
  • +
  • This results in low-latency, high-throughput computation without the need for handwritten intrinsics — the compiler handles the vectorization automatically.
  • +
+
+

Why ARM, Why LLVM

+

During design exploration, we tested SIMD on different architectures and found ARM (AArch64) with NEON/SVE/SVE2 provided excellent performance for our workloads.

+

Instead of writing custom intrinsics, Numerix compiles with SIMD flags and lets LLVM handle vectorization:

+
RUSTFLAGS="-C target-feature=+neon,+sve,+sve2" \
cargo build --release --target aarch64-unknown-linux-gnu
+
    +
  • +

    This approach works well because operations are straightforward, data is aligned, and compiler auto-vectorization is reliable.

    +
  • +
  • +

    AMD/x86 builds are equally supported — enabling their SIMD extensions is just a matter of changing build flags.

    +
  • +
+

Request Model and Flow

+
    +
  1. Client calls gRPC numerix.Numerix/Compute with: +
      +
    • schema: ordered feature names
    • +
    • entity_scores: per-entity vectors (string or bytes)
    • +
    • compute_id: integer identifier for the expression
    • +
    • data_type (optional): e.g., fp32 or fp64
    • +
    +
  2. +
  3. Service fetches the postfix expression for compute_id which was pre-fetched from etcd.
  4. +
  5. Request is validated for schema and data shape.
  6. +
  7. The stack-based evaluator executes the expression in O(n) over tokens, with vectorized inner operations.
  8. +
  9. Response returns computation_score_data or a structured error.
  10. +
+
+

Why Postfix Expressions

+
    +
  • Stored in etcd as postfix (Reverse Polish) notation.
  • +
  • Postfix makes evaluation parser-free and linear time.
  • +
  • Execution uses a stack machine: +
      +
    • Push operands (feature vectors).
    • +
    • Pop, compute, and push results for each operator.
    • +
    +
  • +
  • Benefits: predictable runtime, compiler-friendly loops, cache efficiency.
  • +
+

gRPC Interface

+
    +
  • Service: numerix.Numerix
  • +
  • RPC: Compute(NumerixRequestProto) → NumerixResponseProto
  • +
  • Request fields: schema, entity_scores, compute_id, optional data_type
  • +
  • Response fields: computation_score_data or error
  • +
+

Example (grpcurl):

+
grpcurl -plaintext \
-import-path ./numerix/src/protos/proto \
-proto numerix.proto \
-d '{
"entityScoreData": {
"schema": ["feature1", "feature2"],
"entityScores": [ { "stringData": { "values": ["1.0", "2.0"] } } ],
"computeId": "1001",
"dataType": "fp32"
}
}' \
localhost:8080 numerix.Numerix/Compute
+
+

Observability

+
    +
  • Datadog (DogStatsD) metrics publication via UDP client: +
      +
    • Latency (P50/P95/P99), error rate, RPS, internal failures
    • +
    • Configurable sampling rate via environment variables
    • +
    +
  • +
  • Optional /metrics HTTP endpoint can be enabled for local debugging.
  • +
+
+

Environments

+
    +
  • Kubernetes (K8s), including GKE and EKS
  • +
  • Multi-arch builds: amd64, arm64.
  • +
  • ARM builds ship with NEON/SVE/SVE2 enabled.
  • +
+
+

Key Takeaways

+
    +
  • Minimal service surface: gRPC + etcd.
  • +
  • No custom intrinsics — portable across ARM & AMD via compiler flags.
  • +
  • Supports both string and byte input, internally converted to aligned fp32/fp64 vectors.
  • +
  • Stack-based postfix evaluation : linear time, cache-friendly.
  • +
  • Predictable, ultra-low-latency performance.
  • +
+

Contributing

+

We welcome contributions from the community! Please see our Contributing Guide for details on how to get started.

+

Community & Support

+ +

License

+

BharatMLStack is open-source software licensed under the BharatMLStack Business Source License 1.1.

+
+
Built with ❤️ for the ML community from Meesho
+
If you find this useful, ⭐️ the repo — your support means the world to us!
+ + \ No newline at end of file diff --git a/docs/numerix/v1.0.0/benchmarks/index.html b/docs/numerix/v1.0.0/benchmarks/index.html new file mode 100644 index 00000000..a741f8e9 --- /dev/null +++ b/docs/numerix/v1.0.0/benchmarks/index.html @@ -0,0 +1,48 @@ + + + + + +Benchmarks | BharatMLStack + + + + + + + + +

Benchmarks (PoC)

+

This PoC measures the performance of vector addition in Rust with and without compiler SIMD optimizations. Requests consist of repeated fixed-size vector addition operations processed in parallel by the CPU. These results provide perspective on how much faster SIMD makes vectorized computations, and similar improvements are expected for other vectorized operations in Numerix.

+

System Configuration

+
    +
  • Instance Type: c4a-highcpu-16
  • +
  • Processor: Google Axion (ARMv9, 64-bit)
  • +
  • SIMD Extension: SVE2
  • +
  • OS: Linux (Ubuntu 22.04)
  • +
  • Rust Version: rustc 1.80.0
  • +
  • Target Triple: aarch64-unknown-linux-gnu
  • +
+

Vector Addition Performance

+

With SIMD

+
Vector Dimns per opIterationsThroughput (GiB/s)Total CPU (raw)Total CPU (normalized)
100.39626 ns170,057,457,941376.041564%97.75%
500.6641 ns94,342,709,0951121.91590%99.38%
1001.1522 ns51,705,835,3971286.91560%97.50%
5005.0649 ns12,061,753,66114711538%96.12%
10009.648 ns6,488,848,7051544.51570%98.12%
500052.925 ns1,169,316,8131407.81590%99.38%
10000114.68 ns555,779,9811299.41592%99.50%
50000644.60 ns94,372,1531155.91560%97.50%
1000001.4530 µs42,502,2011025.51526%95.38%
+

Without SIMD

+
Vector Dimns per opIterationsThroughput (GiB/s)Total CPU (raw)Total CPU (normalized)
103.196 ns1,000,000,00025.031313%82.06%
503.866 ns1,000,000,000103.461417%88.56%
1005.867 ns1,000,000,000136.351495%93.44%
50019.25 ns1,000,000,000207.811600%100.00%
100033.91 ns1,000,000,000235.921600%100.00%
5000162.1 ns448,785,386246.711600%100.00%
10000332.0 ns208,428,151240.941600%100.00%
500001,740 ns39,247,646229.931600%100.00%
1000003,401 ns19,598,293235.241600%100.00%
+
+

Normalization: Total CPU (normalized) = Total CPU (raw) / 16, since 1600% equals full utilization on a 16‑core machine.

+
+

Observations

+
    +
  • SIMD provides large speedups across all vector sizes: overall throughput improvements range from roughly 4–15× versus Without SIMD.
  • +
  • For small vectors (10–100), throughput gains are about 9–15×, with ns/op reduced proportionally.
  • +
  • For larger vectors (500–100000), speedups stabilize around ~4–7× as memory bandwidth pressure increases.
  • +
  • CPU saturation: Without SIMD reaches 100% normalized CPU at and beyond 500 elements, whereas With SIMD typically operates at ~95–99% normalized CPU yet delivers substantially higher throughput at similar CPU.
  • +
  • Per‑CPU efficiency: With SIMD, throughput per unit of CPU is much higher, reflecting better vector unit utilization and fewer instructions per element.
  • +
  • Absolute values depend on hardware and load; the relative differential reflects the benefit of compiler SIMD optimizations.
  • +
+
+

⚠ Note: Absolute numbers depend on CPU frequency, memory locality, and system load. These results are meant +to show relative SIMD benefits.

+
+ + \ No newline at end of file diff --git a/docs/numerix/v1.0.0/functionalities/index.html b/docs/numerix/v1.0.0/functionalities/index.html new file mode 100644 index 00000000..820fa713 --- /dev/null +++ b/docs/numerix/v1.0.0/functionalities/index.html @@ -0,0 +1,85 @@ + + + + + +Key Functionalities | BharatMLStack + + + + + + + + +

Numerix — Key Functionalities

+

Overview

+

Numerix evaluates mathematical expressions over feature matrices with a simple, low-latency gRPC surface. Each request references a compute_id; Numerix resolves a postfix expression, maps variables to input columns, and evaluates it over fp32/fp64 vectors with compiler-assisted SIMD.

+

🚀 Core Capabilities

+

Expression Evaluation

+
    +
  • Postfix execution: Linear-time, stack-based evaluation over aligned vectors.
  • +
  • Vectorized math: Compiler autovectorization (NEON/SVE on ARM, SSE/AVX on x86) — no handwritten intrinsics.
  • +
  • Typed compute: Inputs converted to fp32 or fp64 for predictable performance.
  • +
+

Input Formats

+
    +
  • Strings: Easy-to-produce feature values (converted internally).
  • +
  • Bytes: Efficient wire format for high-throughput paths.
  • +
+

Request Patterns

+
    +
  • Single entity or batch: Multiple entity_scores per call.
  • +
  • Schema-driven: Column order in schema drives variable mapping in expressions.
  • +
+

🎯 Developer Experience

+
    +
  • gRPC API: Simple single RPC — Numerix/Compute.
  • +
  • Protobuf schema: Language-agnostic client generation.
  • +
  • Deterministic behavior: No parsing at request time; expression resolved from registry.
  • +
+

gRPC Service

+
service Numerix {
rpc Compute(NumerixRequestProto) returns (NumerixResponseProto);
}
+

Example Call (grpcurl)

+
grpcurl -plaintext \
-import-path ./numerix/src/protos/proto \
-proto numerix.proto \
-d '{
"entityScoreData": {
"schema": ["feature1", "feature2"],
"entityScores": [ { "stringData": { "values": ["1.0", "2.0"] } } ],
"computeId": "1001",
"dataType": "fp32"
}
}' \
localhost:8080 numerix.Numerix/Compute
+

📊 Observability

+
    +
  • Datadog/DogStatsD: Latency (P50/P95/P99), RPS, error rate via UDP client.
  • +
  • Optional /metrics endpoint for local/adhoc debugging.
  • +
+

⚙️ Configuration & Registry

+
    +
  • etcd registry: compute_id (int) → postfix expression mapping.
  • +
  • Environment-driven config: endpoints, timeouts, sampling rate.
  • +
+

🧪 Example Scenarios

+

Batched evaluation

+
    +
  • Submit multiple entities in one call to reduce RPC overhead; evaluate the same compute_id across all rows.
  • +
+

Mixed input formats

+
    +
  • Start with string inputs for ease; migrate to bytes for performance without changing the expression or API.
  • +
+

🔧 Tuning Knobs

+
    +
  • Data type: choose fp32 (speed) vs fp64 (precision).
  • +
  • Batch size: tune number of entities per call for your p99 vs throughput goals.
  • +
  • Sampling rate: adjust Datadog metric sampling to balance signal vs cost.
  • +
+
+

Contributing

+

We welcome contributions from the community! Please see our Contributing Guide for details on how to get started.

+

Community & Support

+ +

License

+

BharatMLStack is open-source software licensed under the BharatMLStack Business Source License 1.1.

+
+
Built with ❤️ for the ML community from Meesho
+
If you find this useful, ⭐️ the repo — your support means the world to us!
+ + \ No newline at end of file diff --git a/docs/numerix/v1.0.0/index.html b/docs/numerix/v1.0.0/index.html new file mode 100644 index 00000000..8de38ec4 --- /dev/null +++ b/docs/numerix/v1.0.0/index.html @@ -0,0 +1,17 @@ + + + + + +v1.0.0 | BharatMLStack + + + + + + + + + + + \ No newline at end of file diff --git a/docs/numerix/v1.0.0/release-notes/index.html b/docs/numerix/v1.0.0/release-notes/index.html new file mode 100644 index 00000000..72d0f680 --- /dev/null +++ b/docs/numerix/v1.0.0/release-notes/index.html @@ -0,0 +1,89 @@ + + + + + +Release Notes | BharatMLStack + + + + + + + + +

Numerix - Release Notes

+

Version 1.0.0 🚀

+

Release Date: September 2025
+Status: General Availability (GA)

+

The first stable release of Numerix — a Rust-based compute service for evaluating mathematical expressions over feature matrices with very low latency. Numerix executes postfix expressions from an etcd-backed registry using a stack-based evaluator and compiler-assisted SIMD.

+
+

🎯 What's New

+

Core Engine

+
    +
  • Postfix Expression Execution: compute_id → postfix mapping in etcd; parser-free request path.
  • +
  • Stack-Based Evaluator: Linear-time execution over aligned vectors for predictable latency.
  • +
  • Compiler-Assisted SIMD: Relies on LLVM autovectorization (NEON/SVE on ARM; SSE/AVX on x86); no handwritten intrinsics.
  • +
  • Typed Evaluation: Internal conversion to fp32/fp64 for consistent performance/precision.
  • +
+

API Surface

+
    +
  • gRPC: Single RPC — numerix.Numerix/Compute.
  • +
  • Input Formats: Strings for ease, bytes for performance; both map to vectorized math internally.
  • +
+

Observability

+
    +
  • Datadog/DogStatsD metrics: Latency (P50/P95/P99), RPS, error rate.
  • +
  • Minimal HTTP diagnostics: /health (and optional /metrics).
  • +
+
+

🚀 Performance & Optimization

+
    +
  • Autovectorized Loops: Tight loops over contiguous memory enable the compiler to emit SIMD instructions automatically.
  • +
  • ARM Focus Option: Excellent results with AArch64; builds can enable NEON/SVE/SVE2:
  • +
+
RUSTFLAGS="-C target-feature=+neon,+sve,+sve2" \
cargo build --release --target aarch64-unknown-linux-gnu
+
    +
  • Deterministic Runtime: No dynamic parsing in hot path; O(n) across tokens with vectorized inner ops.
  • +
+
+

🛠️ APIs

+

gRPC

+
service Numerix {
rpc Compute(NumerixRequestProto) returns (NumerixResponseProto);
}
+

Example call:

+
grpcurl -plaintext \
-import-path ./numerix/src/protos/proto \
-proto numerix.proto \
-d '{
"entityScoreData": {
"schema": ["feature1", "feature2"],
"entityScores": [ { "stringData": { "values": ["1.0", "2.0"] } } ],
"computeId": "1001",
"dataType": "fp32"
}
}' \
localhost:8080 numerix.Numerix/Compute
+
+

🏗️ Deployment & Configuration

+

Environment

+
APPLICATION_PORT=8083
APP_ENV=prd
APP_LOG_LEVEL=ERROR
APP_NAME=numerix

# Performance
CHANNEL_BUFFER_SIZE=10000

# etcd
ETCD_SERVERS=127.0.0.1:2379

# Metrics
METRIC_SAMPLING_RATE=1
TELEGRAF_UDP_HOST=127.0.0.1
TELEGRAF_UDP_PORT=8125
+

Containers

+
    +
  • Multi-arch images: linux/amd64, linux/arm64.
  • +
  • Build targets example: x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu.
  • +
+
+

🔄 Compatibility

+
    +
  • Clients: Any language with gRPC + generated stubs.
  • +
  • Architectures: amd64 and arm64; ARM builds can enable NEON/SVE/SVE2.
  • +
+
+

🐛 Known Issues

+
    +
  1. Introduce a configurable log sampling rate to reduce pod memory usage during computation errors.
  2. +
+

Contributing

+

We welcome contributions from the community! Please see our Contributing Guide for details on how to get started.

+

Community & Support

+ +

License

+

BharatMLStack is open-source software licensed under the BharatMLStack Business Source License 1.1.

+
+
Built with ❤️ for the ML community from Meesho
+
If you find this useful, ⭐️ the repo — your support means the world to us!
+ + \ No newline at end of file diff --git a/docs/online-feature-store/v1.0.0/architecture/index.html b/docs/online-feature-store/v1.0.0/architecture/index.html index e77710ef..a1ab0342 100644 --- a/docs/online-feature-store/v1.0.0/architecture/index.html +++ b/docs/online-feature-store/v1.0.0/architecture/index.html @@ -4,15 +4,15 @@ Architecture | BharatMLStack - - - + + + -

BharatMLStack - Online Feature Store (OnFS)

+

BharatMLStack - Online Feature Store (OnFS)

The Online Feature Store (OnFS) is part of BharatMLStack, designed to support real-time ML workloads through low-latency feature retrieval and flexible feature ingestion pipelines. It ensures that features generated offline or online are immediately accessible for inference.


BharatMLStack&#39;s Online-feature-store Architecture

@@ -121,6 +121,6 @@

LicenseBharatMLStack Business Source License 1.1.


Built with ❤️ for the ML community from Meesho
-
If you find this useful, ⭐️ the repo — your support means the world to us!

+
If you find this useful, ⭐️ the repo — your support means the world to us!
\ No newline at end of file diff --git a/docs/online-feature-store/v1.0.0/benchmarks/index.html b/docs/online-feature-store/v1.0.0/benchmarks/index.html index b66a3f67..a94269ff 100644 --- a/docs/online-feature-store/v1.0.0/benchmarks/index.html +++ b/docs/online-feature-store/v1.0.0/benchmarks/index.html @@ -4,15 +4,15 @@ Benchmarks | BharatMLStack - - - + + + -

Serialization Performance Benchmarks

+

Serialization Performance Benchmarks

Summary

This report presents comprehensive benchmark results comparing three serialization formats for the BharatML Online Feature Store:

    @@ -116,6 +116,6 @@

    Raw Benchmark Output [Uncompressed Data]

    goos: darwin
    goarch: arm64
    pkg: github.com/Meesho/BharatMLStack/online-feature-store/internal/data/blocks
    BenchmarkInt32SerializationPSDB/PSDB/Size-100-10 1940238 625.3 ns/op 409.0 bytes 461 B/op 4 allocs/op
    BenchmarkInt32SerializationPSDB/PSDB/Size-1000-10 288300 4056 ns/op 4009 bytes 4143 B/op 4 allocs/op
    BenchmarkInt32SerializationPSDB/PSDB/Size-10000-10 32144 37357 ns/op 40009 bytes 41032 B/op 4 allocs/op
    BenchmarkInt32SerializationPSDB/PSDB/Size-100000-10 3244 359932 ns/op 400009 bytes 401572 B/op 4 allocs/op
    BenchmarkInt32SerializationProto3/Proto3/Size-100-10 1703066 695.9 ns/op 486.0 bytes 768 B/op 2 allocs/op
    BenchmarkInt32SerializationProto3/Proto3/Size-1000-10 194142 6004 ns/op 4885 bytes 5632 B/op 2 allocs/op
    BenchmarkInt32SerializationProto3/Proto3/Size-10000-10 20937 57674 ns/op 48734 bytes 49408 B/op 2 allocs/op
    BenchmarkInt32SerializationProto3/Proto3/Size-100000-10 2085 556541 ns/op 487263 bytes 491776 B/op 2 allocs/op
    BenchmarkInt32SerializationArrow/Arrow/Size-100-10 302257 3831 ns/op 680.0 bytes 7032 B/op 66 allocs/op
    BenchmarkInt32SerializationArrow/Arrow/Size-1000-10 228718 5191 ns/op 4280 bytes 15544 B/op 66 allocs/op
    BenchmarkInt32SerializationArrow/Arrow/Size-10000-10 52482 23173 ns/op 40280 bytes 122617 B/op 66 allocs/op
    BenchmarkInt32SerializationArrow/Arrow/Size-100000-10 9765 120081 ns/op 400280 bytes 957948 B/op 66 allocs/op
    BenchmarkInt32SerializationComparison/Comparison/Size-100/PSDB-10 1919401 670.2 ns/op 409.0 bytes 461 B/op 4 allocs/op
    BenchmarkInt32SerializationComparison/Comparison/Size-100/Proto3-10 1733599 693.2 ns/op 490.0 bytes 768 B/op 2 allocs/op
    BenchmarkInt32SerializationComparison/Comparison/Size-100/Arrow-10 304066 3896 ns/op 680.0 bytes 7032 B/op 66 allocs/op
    BenchmarkInt32SerializationComparison/Comparison/Size-1000/PSDB-10 290784 4074 ns/op 4009 bytes 4143 B/op 4 allocs/op
    BenchmarkInt32SerializationComparison/Comparison/Size-1000/Proto3-10 196962 6034 ns/op 4882 bytes 5632 B/op 2 allocs/op
    BenchmarkInt32SerializationComparison/Comparison/Size-1000/Arrow-10 227908 5240 ns/op 4280 bytes 15544 B/op 66 allocs/op
    BenchmarkInt32SerializationComparison/Comparison/Size-10000/PSDB-10 31732 38064 ns/op 40009 bytes 41024 B/op 4 allocs/op
    BenchmarkInt32SerializationComparison/Comparison/Size-10000/Proto3-10 20827 57670 ns/op 48745 bytes 49408 B/op 2 allocs/op
    BenchmarkInt32SerializationComparison/Comparison/Size-10000/Arrow-10 52000 23557 ns/op 40280 bytes 122617 B/op 66 allocs/op
    BenchmarkInt32SerializationComparison/Comparison/Size-100000/PSDB-10 3268 363817 ns/op 400009 bytes 401575 B/op 4 allocs/op
    BenchmarkInt32SerializationComparison/Comparison/Size-100000/Proto3-10 2097 559621 ns/op 487247 bytes 491776 B/op 2 allocs/op
    BenchmarkInt32SerializationComparison/Comparison/Size-100000/Arrow-10 10000 118489 ns/op 400280 bytes 957947 B/op 66 allocs/op
    BenchmarkInt32SizeComparison/SizeOnly/Size-100-10 1000000000 0.0000223 ns/op 680.0 arrow_bytes 170.0 arrow_ratio_pct 490.0 proto3_bytes 122.5 proto3_ratio_pct 409.0 psdb_bytes 102.2 psdb_ratio_pct 400.0 raw_bytes
    BenchmarkInt32SizeComparison/SizeOnly/Size-1000-10 1000000000 0.0000379 ns/op 4280 arrow_bytes 107.0 arrow_ratio_pct 4881 proto3_bytes 122.0 proto3_ratio_pct 4009 psdb_bytes 100.2 psdb_ratio_pct 4000 raw_bytes
    BenchmarkInt32SizeComparison/SizeOnly/Size-10000-10 1000000000 0.0001182 ns/op 40280 arrow_bytes 100.7 arrow_ratio_pct 48717 proto3_bytes 121.8 proto3_ratio_pct 40009 psdb_bytes 100.0 psdb_ratio_pct 40000 raw_bytes
    BenchmarkInt32SizeComparison/SizeOnly/Size-100000-10 1000000000 0.001034 ns/op 400280 arrow_bytes 100.1 arrow_ratio_pct 487225 proto3_bytes 121.8 proto3_ratio_pct 400009 psdb_bytes 100.0 psdb_ratio_pct 400000 raw_bytes
    BenchmarkInt32MemoryEfficiency/Memory/Size-100/PSDB_Pooled-10 1926676 622.4 ns/op 461 B/op 4 allocs/op
    BenchmarkInt32MemoryEfficiency/Memory/Size-100/Proto3-10 1713428 685.0 ns/op 768 B/op 2 allocs/op
    BenchmarkInt32MemoryEfficiency/Memory/Size-100/Arrow-10 312584 4029 ns/op 7032 B/op 66 allocs/op
    BenchmarkInt32MemoryEfficiency/Memory/Size-1000/PSDB_Pooled-10 290197 4189 ns/op 4143 B/op 4 allocs/op
    BenchmarkInt32MemoryEfficiency/Memory/Size-1000/Proto3-10 195694 6078 ns/op 5632 B/op 2 allocs/op
    BenchmarkInt32MemoryEfficiency/Memory/Size-1000/Arrow-10 224722 5190 ns/op 15544 B/op 66 allocs/op
    BenchmarkInt32MemoryEfficiency/Memory/Size-10000/PSDB_Pooled-10 31898 37684 ns/op 41029 B/op 4 allocs/op
    BenchmarkInt32MemoryEfficiency/Memory/Size-10000/Proto3-10 20840 58032 ns/op 49408 B/op 2 allocs/op
    BenchmarkInt32MemoryEfficiency/Memory/Size-10000/Arrow-10 51440 24049 ns/op 122617 B/op 66 allocs/op
    BenchmarkInt32MemoryEfficiency/Memory/Size-100000/PSDB_Pooled-10 3325 357690 ns/op 401814 B/op 4 allocs/op
    BenchmarkInt32MemoryEfficiency/Memory/Size-100000/Proto3-10 2158 559694 ns/op 491776 B/op 2 allocs/op
    BenchmarkInt32MemoryEfficiency/Memory/Size-100000/Arrow-10 9622 117515 ns/op 957948 B/op 66 allocs/op
    BenchmarkInt32Throughput/Throughput/PSDB-10 290912 4101 ns/op 975.31 MB/s 4143 B/op 4 allocs/op
    BenchmarkInt32Throughput/Throughput/Proto3-10 199087 6005 ns/op 666.12 MB/s 5632 B/op 2 allocs/op
    BenchmarkInt32Throughput/Throughput/Arrow-10 229594 5207 ns/op 768.25 MB/s 15544 B/op 66 allocs/op
    BenchmarkGetPSDBPoolWithoutPool-10 23836599 50.64 ns/op 192 B/op 1 allocs/op
    BenchmarkGetPSDBPoolWithPool-10 100000000 10.76 ns/op 0 B/op 0 allocs/op
    PASS
    ok github.com/Meesho/BharatMLStack/online-feature-store/internal/data/blocks 58.891s

    -

    Benchmarks run on Apple Silicon (ARM64) with Go 1.22.12. Results may vary on different architectures and Go versions.

+

Benchmarks run on Apple Silicon (ARM64) with Go 1.22.12. Results may vary on different architectures and Go versions.

\ No newline at end of file diff --git a/docs/online-feature-store/v1.0.0/data-formats/index.html b/docs/online-feature-store/v1.0.0/data-formats/index.html index 300d6d37..e2446a6e 100644 --- a/docs/online-feature-store/v1.0.0/data-formats/index.html +++ b/docs/online-feature-store/v1.0.0/data-formats/index.html @@ -4,15 +4,15 @@ Data Formats | BharatMLStack - - - + + + -

Data Format for Permanent & Cache Storage

+

Data Format for Permanent & Cache Storage

In this section we will go through the data-formats which is at the hear of online-feature-store, it's inspired form other storage efficient formats like parquet & arrow, but custom made to deliver in constraint environment. The two key data-formats are:

  • PSDB - Permanent Storage Data Block used wile storing data in ScyllaDB
  • @@ -167,6 +167,6 @@

    Opti
  • Versioning Support: Layout version is stored as the first byte to enable format upgrades while maintaining backward compatibility.

Diagram below explains how compute cycles are saved by partial de-compression.

-

CSDB Partial Decompression

+

CSDB Partial Decompression

\ No newline at end of file diff --git a/docs/online-feature-store/v1.0.0/functionalities/index.html b/docs/online-feature-store/v1.0.0/functionalities/index.html index 4b66f528..dd05aa9b 100644 --- a/docs/online-feature-store/v1.0.0/functionalities/index.html +++ b/docs/online-feature-store/v1.0.0/functionalities/index.html @@ -4,15 +4,15 @@ Key Functionalities | BharatMLStack - - - + + + -

Online Feature Store - Key Functionalities

+

Online Feature Store - Key Functionalities

Overview

The BharatML Online Feature Store is a high-performance, production-ready system designed to serve machine learning features with sub-10ms P99 latency and 1M+ RPS capacity. It bridges the gap between offline feature engineering and real-time model inference.

🚀 Core Capabilities

@@ -115,6 +115,6 @@

LicenseBharatMLStack Business Source License 1.1.


Built with ❤️ for the ML community from Meesho
-
If you find this useful, ⭐️ the repo — your support means the world to us!

+
If you find this useful, ⭐️ the repo — your support means the world to us!
\ No newline at end of file diff --git a/docs/online-feature-store/v1.0.0/index.html b/docs/online-feature-store/v1.0.0/index.html index 038a7ea3..6c38f703 100644 --- a/docs/online-feature-store/v1.0.0/index.html +++ b/docs/online-feature-store/v1.0.0/index.html @@ -3,15 +3,15 @@ -v1.0.0 | BharatMLStack - - - +v1.0.0 | BharatMLStack + + + - + \ No newline at end of file diff --git a/docs/online-feature-store/v1.0.0/release-notes/index.html b/docs/online-feature-store/v1.0.0/release-notes/index.html index 4773cd02..d6f22f70 100644 --- a/docs/online-feature-store/v1.0.0/release-notes/index.html +++ b/docs/online-feature-store/v1.0.0/release-notes/index.html @@ -4,15 +4,15 @@ Release Notes | BharatMLStack - - - + + + -

Online Feature Store - Release Notes

+ +
If you find this useful, ⭐️ the repo — your support means the world to us!
\ No newline at end of file diff --git a/docs/quick-start/v1.0.0/quick-start/index.html b/docs/quick-start/v1.0.0/quick-start/index.html index 43b3a215..41c009bb 100644 --- a/docs/quick-start/v1.0.0/quick-start/index.html +++ b/docs/quick-start/v1.0.0/quick-start/index.html @@ -4,15 +4,15 @@ Quick Start | BharatMLStack - - - + + + -

BharatML Stack Quick Start Guide

+ +
If you find this useful, ⭐️ the repo — your support means the world to us!
\ No newline at end of file diff --git a/docs/sdks/go/v1.0.0/feature_client/index.html b/docs/sdks/go/v1.0.0/feature_client/index.html index 63ed7f2b..6a83cd31 100644 --- a/docs/sdks/go/v1.0.0/feature_client/index.html +++ b/docs/sdks/go/v1.0.0/feature_client/index.html @@ -4,15 +4,15 @@ GRPC Feature client | BharatMLStack - - - + + + -

Build Status +

+
If you find this useful, ⭐️ the repo — your support means the world to us!
\ No newline at end of file diff --git a/docs/sdks/python/v1.0.0/grpc_feature_client/index.html b/docs/sdks/python/v1.0.0/grpc_feature_client/index.html index 8de4755e..d7de40ad 100644 --- a/docs/sdks/python/v1.0.0/grpc_feature_client/index.html +++ b/docs/sdks/python/v1.0.0/grpc_feature_client/index.html @@ -4,15 +4,15 @@ GRPC Feature client | BharatMLStack - - - + + + -

GRPC Feature Client

+

GRPC Feature Client

PyPI version Build Status Python 3.7+ @@ -46,7 +46,7 @@

GRPCClientC
class GRPCClientConfig:
def __init__(
self,
server_address: str,
job_id: str,
job_token: str,
use_tls: bool = False,
timeout_seconds: float = 30.0,
metadata: Dict[str, str] = None,
max_receive_message_length: int = 4 * 1024 * 1024,
max_send_message_length: int = 4 * 1024 * 1024
)

Usage Examples

Persisting Features

-
from grpc_feature_client import GRPCFeatureClient, GRPCClientConfig

config = GRPCClientConfig(
server_address="feature-store.example.com:50051",
job_id="predator",
job_token="api-token"
)

client = GRPCFeatureClient(config)

# Persist real-time features
result = client.persist_features(
entity_label="user_interaction",
keys_schema=["user_id", "session_id"],
feature_group_schemas=[{
"label": "realtime_features",
"feature_labels": ["click_count", "page_views"]
}],
data_rows=[{
"user_id": "u123",
"session_id": "s456",
"click_count": 5,
"page_views": 3
}]
)

print(f"Persist result: {result}")
+
from grpc_feature_client import GRPCFeatureClient, GRPCClientConfig

config = GRPCClientConfig(
server_address="feature-store.example.com:50051",
job_id="predator-service",
job_token="api-token"
)

client = GRPCFeatureClient(config)

# Persist real-time features
result = client.persist_features(
entity_label="user_interaction",
keys_schema=["user_id", "session_id"],
feature_group_schemas=[{
"label": "realtime_features",
"feature_labels": ["click_count", "page_views"]
}],
data_rows=[{
"user_id": "u123",
"session_id": "s456",
"click_count": 5,
"page_views": 3
}]
)

print(f"Persist result: {result}")

Retrieving Features

# Retrieve features for ML model inference
features = client.retrieve_decoded_features(
entity_label="user_interaction",
feature_groups=[{
"label": "user_features",
"feature_labels": ["age", "location"]
}],
keys_schema=["user_id"],
entity_keys=[["u123"], ["u456"]]
)

print(f"Retrieved features: {features}")

With Context Management

@@ -85,6 +85,6 @@

LicenseBharatMLStack Business Source License 1.1.


Built with ❤️ for the ML community from Meesho
-
If you find this useful, ⭐️ the repo — your support means the world to us!

+
If you find this useful, ⭐️ the repo — your support means the world to us!
\ No newline at end of file diff --git a/docs/sdks/python/v1.0.0/spark_feature_push_client/index.html b/docs/sdks/python/v1.0.0/spark_feature_push_client/index.html index 140deb5f..afe6e790 100644 --- a/docs/sdks/python/v1.0.0/spark_feature_push_client/index.html +++ b/docs/sdks/python/v1.0.0/spark_feature_push_client/index.html @@ -4,15 +4,15 @@ Spark client | BharatMLStack - - - + + + -

Spark Feature Push Client

+ +
If you find this useful, ⭐️ the repo — your support means the world to us!
\ No newline at end of file diff --git a/docs/sitemap.xml b/docs/sitemap.xml index 215a1dea..b40f123c 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -1 +1 @@ -https://meesho.github.io/BharatMLStack/blogweekly0.5https://meesho.github.io/BharatMLStack/blog/archiveweekly0.5https://meesho.github.io/BharatMLStack/blog/authorsweekly0.5https://meesho.github.io/BharatMLStack/blog/post-oneweekly0.5https://meesho.github.io/BharatMLStack/blog/tagsweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/interaction-storeweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/meeshoweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/mlplatformweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/online-feature-storeweekly0.5https://meesho.github.io/BharatMLStack/markdown-pageweekly0.5https://meesho.github.io/BharatMLStack/weekly0.5https://meesho.github.io/BharatMLStack/category/go-sdkweekly0.5https://meesho.github.io/BharatMLStack/category/online-feature-storeweekly0.5https://meesho.github.io/BharatMLStack/category/python-sdkweekly0.5https://meesho.github.io/BharatMLStack/category/quick-startweekly0.5https://meesho.github.io/BharatMLStack/category/sdksweekly0.5https://meesho.github.io/BharatMLStack/category/trufflebox-uiweekly0.5https://meesho.github.io/BharatMLStack/category/v100weekly0.5https://meesho.github.io/BharatMLStack/online-feature-store/v1.0.0weekly0.5https://meesho.github.io/BharatMLStack/online-feature-store/v1.0.0/architectureweekly0.5https://meesho.github.io/BharatMLStack/online-feature-store/v1.0.0/benchmarksweekly0.5https://meesho.github.io/BharatMLStack/online-feature-store/v1.0.0/data-formatsweekly0.5https://meesho.github.io/BharatMLStack/online-feature-store/v1.0.0/functionalitiesweekly0.5https://meesho.github.io/BharatMLStack/online-feature-store/v1.0.0/release-notesweekly0.5https://meesho.github.io/BharatMLStack/quick-start/v1.0.0/quick-startweekly0.5https://meesho.github.io/BharatMLStack/sdks/go/v1.0.0/feature_clientweekly0.5https://meesho.github.io/BharatMLStack/sdks/python/v1.0.0/grpc_feature_clientweekly0.5https://meesho.github.io/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_clientweekly0.5https://meesho.github.io/BharatMLStack/trufflebox-ui/v1.0.0/userguideweekly0.5 \ No newline at end of file +https://meesho.github.io/BharatMLStack/blogweekly0.5https://meesho.github.io/BharatMLStack/blog/archiveweekly0.5https://meesho.github.io/BharatMLStack/blog/authorsweekly0.5https://meesho.github.io/BharatMLStack/blog/post-fiveweekly0.5https://meesho.github.io/BharatMLStack/blog/post-oneweekly0.5https://meesho.github.io/BharatMLStack/blog/post-threeweekly0.5https://meesho.github.io/BharatMLStack/blog/post-threeweekly0.5https://meesho.github.io/BharatMLStack/blog/post-twoweekly0.5https://meesho.github.io/BharatMLStack/blog/tagsweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/bharatmlstackweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/embedding-searchweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/inferflowweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/interaction-storeweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/llmweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/meeshoweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/mlplatformweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/model-inferenceweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/online-feature-storeweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/tensorrt-llmweekly0.5https://meesho.github.io/BharatMLStack/blog/tags/vllmweekly0.5https://meesho.github.io/BharatMLStack/markdown-pageweekly0.5https://meesho.github.io/BharatMLStack/weekly0.5https://meesho.github.io/BharatMLStack/category/go-sdkweekly0.5https://meesho.github.io/BharatMLStack/category/inferflowweekly0.5https://meesho.github.io/BharatMLStack/category/numerixweekly0.5https://meesho.github.io/BharatMLStack/category/online-feature-storeweekly0.5https://meesho.github.io/BharatMLStack/category/python-sdkweekly0.5https://meesho.github.io/BharatMLStack/category/quick-startweekly0.5https://meesho.github.io/BharatMLStack/category/sdksweekly0.5https://meesho.github.io/BharatMLStack/category/trufflebox-uiweekly0.5https://meesho.github.io/BharatMLStack/category/v100weekly0.5https://meesho.github.io/BharatMLStack/inferflow/v1.0.0weekly0.5https://meesho.github.io/BharatMLStack/inferflow/v1.0.0/architectureweekly0.5https://meesho.github.io/BharatMLStack/inferflow/v1.0.0/configurationweekly0.5https://meesho.github.io/BharatMLStack/inferflow/v1.0.0/functionalitiesweekly0.5https://meesho.github.io/BharatMLStack/inferflow/v1.0.0/release-notesweekly0.5https://meesho.github.io/BharatMLStack/numerix/v1.0.0weekly0.5https://meesho.github.io/BharatMLStack/numerix/v1.0.0/architectureweekly0.5https://meesho.github.io/BharatMLStack/numerix/v1.0.0/benchmarksweekly0.5https://meesho.github.io/BharatMLStack/numerix/v1.0.0/functionalitiesweekly0.5https://meesho.github.io/BharatMLStack/numerix/v1.0.0/release-notesweekly0.5https://meesho.github.io/BharatMLStack/online-feature-store/v1.0.0weekly0.5https://meesho.github.io/BharatMLStack/online-feature-store/v1.0.0/architectureweekly0.5https://meesho.github.io/BharatMLStack/online-feature-store/v1.0.0/benchmarksweekly0.5https://meesho.github.io/BharatMLStack/online-feature-store/v1.0.0/data-formatsweekly0.5https://meesho.github.io/BharatMLStack/online-feature-store/v1.0.0/functionalitiesweekly0.5https://meesho.github.io/BharatMLStack/online-feature-store/v1.0.0/release-notesweekly0.5https://meesho.github.io/BharatMLStack/quick-start/v1.0.0/quick-startweekly0.5https://meesho.github.io/BharatMLStack/sdks/go/v1.0.0/feature_clientweekly0.5https://meesho.github.io/BharatMLStack/sdks/python/v1.0.0/grpc_feature_clientweekly0.5https://meesho.github.io/BharatMLStack/sdks/python/v1.0.0/spark_feature_push_clientweekly0.5https://meesho.github.io/BharatMLStack/trufflebox-ui/v1.0.0/userguideweekly0.5 \ No newline at end of file diff --git a/docs/trufflebox-ui/v1.0.0/userguide/index.html b/docs/trufflebox-ui/v1.0.0/userguide/index.html index 4933b1fe..0c2e7fc2 100644 --- a/docs/trufflebox-ui/v1.0.0/userguide/index.html +++ b/docs/trufflebox-ui/v1.0.0/userguide/index.html @@ -4,15 +4,15 @@ User Manual | BharatMLStack - - - + + + -

Usage Guide

+

Usage Guide

This guide covers the complete setup and usage of the Online Feature Store system, including the core services (Online Feature Store and Horizon) and the TruffleBox UI for feature management.

Table of Contents

+
If you find this useful, ⭐️ the repo — your support means the world to us!
\ No newline at end of file diff --git a/flashring/.cursor/rules/global/golang/code-quality.mdc b/flashring/.cursor/rules/global/golang/code-quality.mdc new file mode 100644 index 00000000..9a48e63e --- /dev/null +++ b/flashring/.cursor/rules/global/golang/code-quality.mdc @@ -0,0 +1,17 @@ +--- +description: "Guidelines for maintaining code quality, clarity, and consistency across imports, function usage, and documentation" +globs: +alwaysApply: false +--- + +### Import statements quality +1. Do not change the import order of existing import files and packages, just add the new ones +2. Avoid wild card imports + +### Functions usage +1. Do not change the private functions to public unless we want other packages to use it +2. If the same package is using the function then keep it private + +### Code comments and documentation +1. Add comments only when necessary, do not add comments when the code itself gives the understanding +2. Add comments for architectural decision diff --git a/flashring/.cursor/rules/global/golang/compliance.mdc b/flashring/.cursor/rules/global/golang/compliance.mdc new file mode 100644 index 00000000..2b802036 --- /dev/null +++ b/flashring/.cursor/rules/global/golang/compliance.mdc @@ -0,0 +1,36 @@ +--- +description: "Provide the list of rules which are obeyed in every response" +globs: +alwaysApply: true +--- + +# Rule Compliance Tracking + +## Response Format Requirement +When responding to user queries about code patterns, architecture, or implementation examples: + +1. **Always List Obeyed Rules**: At the end of your response, include a section titled "**Rules Followed:**" that lists the specific rules from the codebase that are being obeyed or demonstrated in your response. + +2. **Rule Identification**: Identify rules from the following files: + - `.cursor/rules/unit-testing.mdc` + - `.cursor/rules/requirement-planning.mdc` + - `.cursor/rules/code-quality.mdc` + - `.cursor/rules/compliance.mdc` + +3. **Example Format**: + ``` + **Rules Followed:** + - Dependency Injection Pattern + - Configuration Management + - Interface Design + ``` + +4. **Context Awareness**: Only list rules that are actually relevant to the specific response or examples provided. + +5. **Rule Verification**: When analyzing code examples, verify which rule categories are being followed and explicitly mention the rule headings. + +## Implementation Guidelines +- Scan the codebase for examples that demonstrate rule compliance +- Provide concrete code examples when possible +- Explain how the examples follow the specific rule categories +- Use the rule headings/categories from the source files when listing them diff --git a/flashring/.cursor/rules/global/golang/data-interface-concurrency-errors.mdc b/flashring/.cursor/rules/global/golang/data-interface-concurrency-errors.mdc new file mode 100644 index 00000000..f359b79e --- /dev/null +++ b/flashring/.cursor/rules/global/golang/data-interface-concurrency-errors.mdc @@ -0,0 +1,61 @@ +--- +description: These rules cover data shapes, allocation, interface design, and safe concurrency/error handling—areas where AI can subtly violate idioms or introduce leaks and races. +alwaysApply: false +globs: *.go +--- + +### Effective Go Rules: Data, Allocation, Interfaces, Concurrency, Errors + +These rules cover data shapes, allocation, interface design, and safe concurrency/error handling—areas where AI can subtly violate idioms or introduce leaks and races. + +## Arrays, Slices, Maps +- Reassign the result of `append`; capacity may change. +- Preallocate capacity when known; use `copy` for duplication. +- If copying a slice or map, the pointers nested in these will not be copied. +- Maps: missing keys yield zero values; use comma-ok to test presence. + +Example: +```go +v, ok := m[key] +if !ok { /* handle missing */ } +``` + +## Variadics & Append +- Use `...T` for flexible APIs; forward with `f(v...)`. +- Concatenate slices with `append(dst, src...)`. + + +## Methods: Pointer vs Value +- Pointer receivers for mutation/big copies. + +## Interfaces +- Define small, behavior-driven interfaces near use sites. +- Constructors should return the narrowest interface needed. +- Convert types to reuse method sets (e.g., `sort.IntSlice(s).Sort()`). + + +## Concurrency Basics +- Start goroutines only when beneficial; ensure they can terminate. +- Use channels for synchronization/communication; avoid shared memory without coordination. + +Use Worker pool at appropriate places: +```go +jobs := make(chan Job) +for i := 0; i < N; i++ { go func() { for j := range jobs { handle(j) } }() } +``` + +Channel ownership: +- Close channels only from the sender/owner. + +## Context & Cancellation +- Accept `context.Context` and honor `Done()` for long-lived operations. +- Avoid `time.Sleep` polling; use timers/tickers with `select`. + +## Panic, Recover, Errors +- Prefer `error` returns; reserve `panic` for unrecoverable programmer errors. +- At boundaries, `defer` + `recover` to convert internal panics to errors; type-assert expected panic values. +- Structure error strings without caps/punctuation; prefix with operation or package when helpful. +- Avoid double-reporting (log and return); choose a single owner. +- Use rich error types (ex: `*os.PathError`) and `%w` wrapping. +- Always try to return a meaningfull error code and message, client should be able to find out the failure reason without exposing internal details. +- Either log or return - not both. If you're returning an API response, then log it as well. diff --git a/flashring/.cursor/rules/global/golang/formatting-control.mdc b/flashring/.cursor/rules/global/golang/formatting-control.mdc new file mode 100644 index 00000000..e9f6d7ec --- /dev/null +++ b/flashring/.cursor/rules/global/golang/formatting-control.mdc @@ -0,0 +1,34 @@ +--- +description: These rules focus on the places where AI often drifts from idiomatic Go,, naming that avoids stutter, brace placement, early-returns, and minimalistic control flow. Follow these to produce idiomatic, readable Go. +alwaysApply: false +globs: *.go +--- + +### Effective Go Rules: Formatting, Comments, Naming, Semicolons, Control Flow + +These rules focus on the places where AI often drifts from idiomatic Go: formatting handled by tools, naming that avoids stutter, brace placement, early-returns, and minimalistic control flow. Follow these to produce idiomatic, readable Go. + + +## Naming +- Do not prefix getters with `Get`; prefer `Owner()` over `GetOwner()`; setters as `SetOwner(x)`. + +## Control Flow Essentials +- Prefer early returns for errors; let the success path flow downward. +- Omit `else` when the `if` body ends in `return/break/continue`. +- Use `if`/`switch` init statements to scope locals. +- Prefer `switch` over long `if-else` chains; avoid implicit fallthrough. + +## `defer` and Resources +- Place `defer` immediately after acquiring a resource; args evaluated at `defer` time. +- Deferred calls run LIFO. Avoid deferring inside hot loops. + +## Printing and Diagnostics +- Prefer `%v` for values, `%+v` to include field names, `%#v` for Go syntax, `%T` for type. + +## Shadowing and Short Decls +- Reuse `err` with `:=` when at least one new variable exists; avoid accidental shadowing across scopes. +- Declare variables at first use; avoid predeclaring far from usage. + + +## Extra +- Prefer `const` for stable magic numbers; otherwise localize and comment literals. diff --git a/flashring/.cursor/rules/global/golang/requirement-planning.mdc b/flashring/.cursor/rules/global/golang/requirement-planning.mdc new file mode 100644 index 00000000..868ffa59 --- /dev/null +++ b/flashring/.cursor/rules/global/golang/requirement-planning.mdc @@ -0,0 +1,12 @@ +--- +description: "Promotes thorough requirement analysis, careful planning, and implementation of robust, general-purpose solutions." +alwaysApply: false +--- +### Requirement Understanding + +Before creating a plan you MUST ask questions from the user to get clarity on the problem statement + +1. Break down a problem statement into smaller problem statements +2. Please write a high quality, general purpose solution. Implement a solution that works correctly for all valid inputs, not just the test cases. Do not hard-code values or create solutions that only work for specific test inputs. Instead, implement the actual logic that solves the problem generally. +3. Focus on understanding the problem requirements and implementing the correct algorithm. Tests are there to verify correctness, not to define the solution. Provide a principled implementation that follows best practices and software design principles. +4. If the task is unreasonable or infeasible, or if any of the tests are incorrect, please tell me. The solution should be robust, maintainable, and extendable. diff --git a/flashring/.cursor/rules/global/golang/unit-testing.mdc b/flashring/.cursor/rules/global/golang/unit-testing.mdc new file mode 100644 index 00000000..c159d66f --- /dev/null +++ b/flashring/.cursor/rules/global/golang/unit-testing.mdc @@ -0,0 +1,108 @@ +--- +description: "Go testing patterns including test structure, mocking, test data, assertions and more" +globs: *.go +alwaysApply: false +--- + +# Go Testing Patterns + +## Instructions + +### Test Plan Creation + +When writing unit tests, get clarity on the system under test and come up with a list of what all cases can be possible within that system. Generate the unit test for all those cases + +### Coverage Guidelines +- MUST run `go test -cover` to measure coverage, instead of calculating yourself and aim for 80%+ code coverage for critical business logic +- Focus on testing behavior, not just coverage percentage +- Test error paths and edge cases + +## Test Structure and Organization + +### Test File Organization +- Group related tests using subtests with `t.Run()` +- If there is a single test, then don't use `t.Run()` +- Generate Go tests using testify's suite package for structure wherever applicable + +### Test Naming Conventions +Use descriptive test names that clearly indicate the scenario: + +```go +// ✅ Good - Clear scenario description +func TestConfigService_GetConfig_ReturnsConfigWhenFound(t *testing.T) {} +func TestConfigService_GetConfig_ReturnsErrorWhenNotFound(t *testing.T) {} +func TestConfigService_ValidateConfig_ReturnsErrorOnInvalidData(t *testing.T) {} + +// ❌ Avoid - Vague test names +func TestGetConfig(t *testing.T) {} +func TestValidation(t *testing.T) {} +``` + +## Mocking and Dependencies + +### Interface-Based Mocking +Use interfaces for dependencies to enable easy mocking + +### Mock Setup Patterns +mockRepo := mocks.NewMockRepository(ctrl) +mockRepo.EXPECT(). + GetConfig("test-id"). + Return(&Config{ID: "test-id"}, nil). + Times(1) + +## Test Data and Fixtures + +### Test Data Creation +Create helper functions for building test data where the test data is common + +### Table-Driven Tests +Use table-driven tests for testing multiple scenarios + +## Assertion Patterns + +### Using testify/assert +Prefer testify/assert for better error messages + +```go +// ✅ Good - Clear assertions with testify +assert.NoError(t, err) +assert.Equal(t, expectedValue, actualValue) +assert.Contains(t, slice, element) +assert.Len(t, collection, expectedLength) + +// ❌ Avoid - Basic Go testing with poor error messages +if err != nil { + t.Errorf("expected no error, got %v", err) +} +``` + +### Error Testing +```go +// Testing specific error types +assert.ErrorIs(t, err, ErrConfigNotFound) +assert.ErrorAs(t, err, &validationErr) +assert.NoError(t, err) + +// Testing error messages +assert.EqualError(t, err, "expected error message") +assert.Contains(t, err.Error(), "partial error message") +``` + +## HTTP Handler Testing + +### Testing HTTP Handlers +Use `httptest` for testing HTTP handlers + +## Test Quality + +### Test Organization +- Use setup/teardown functions for complex test scenarios +- Keep tests independent - one test should not depend on another +- Use parallel tests where appropriate: `t.Parallel()` + +### Common Pitfalls to Avoid +1. **Testing Implementation Details**: Focus on behavior, not internal implementation +2. **Ignoring Error Cases**: Always test both success and error scenarios +3. **Flaky Tests**: Avoid time-dependent tests, use deterministic test data +4. **Over-Mocking**: Don't mock everything, test real integrations where valuable +5. **Poor Test Data**: Use realistic test data that reflects production scenarios diff --git a/flashring/.cursor/rules/global/security-golang/secure-golang-rules.mdc b/flashring/.cursor/rules/global/security-golang/secure-golang-rules.mdc new file mode 100644 index 00000000..49cffe70 --- /dev/null +++ b/flashring/.cursor/rules/global/security-golang/secure-golang-rules.mdc @@ -0,0 +1,211 @@ +--- +description: Rules to ensure secure coding in Golang +globs: **/*.go +alwaysApply: true +--- +These rules apply to all Go code in the repository and aim to prevent common security risks through disciplined input handling, safe APIs, and secure defaults. + +All violations must include a clear explanation of which rule was triggered and why, so developers can fix issues quickly.\ +Generated code must not violate these rules. If a rule is violated, add a code comment that explains the problem and proposes a correction. + +## 1. Decode Untrusted Data Safely + +- Do not deserialize untrusted data with unsafe or permissive decoders. Prefer strict JSON or protobuf with size limits. Reject unknown fields. Avoid `encoding/gob` for untrusted input. Use strict YAML decoding only if required. +- + ```go + // Accepts arbitrarily large input and unknown fields + var in any + _ = json.NewDecoder(r.Body).Decode(&in) + ``` +- + ```go + type CreateUser struct { + Name string `json:"name"` + Email string `json:"email"` + } + + dec := json.NewDecoder(http.MaxBytesReader(w, r.Body, 1<<20)) // 1 MB cap + dec.DisallowUnknownFields() + dec.UseNumber() + + var in CreateUser + if err := dec.Decode(&in); err != nil { /* handle */ } + ``` +- **YAML (only if needed):** + ```go + dec := yaml.NewDecoder(bytes.NewReader(b)) + dec.KnownFields(true) // yaml.v3 + if err := dec.Decode(&cfg); err != nil { /* handle */ } + ``` +- **Protobuf JSON:** + ```go + opts := protojson.UnmarshalOptions{DiscardUnknown: false} + if err := opts.Unmarshal(b, msg); err != nil { /* handle */ } + ``` + +## 2. Use Parameterized Queries for Database Access + +- Never format SQL or NoSQL queries with user input. Use placeholders and arguments. Use context with timeouts. +- + ```go + query := fmt.Sprintf("SELECT * FROM users WHERE name = '%s'", name) + rows, _ := db.Query(query) + ``` +- + ```go + ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second) + defer cancel() + + row := db.QueryRowContext(ctx, "SELECT id FROM users WHERE name = $1", name) + ``` + +## 3. Prevent Command Injection + +- Do not pass untrusted input to shells. Use `exec.CommandContext` with fixed program and separate args. Validate inputs against allow lists. +- + ```go + exec.Command("sh", "-c", "ls "+userArg).Run() + ``` +- + ```go + // validatedArg must pass strict allow list or regex + cmd := exec.CommandContext(ctx, "ls", validatedArg) + cmd.Stdout = w + cmd.Stderr = w + _ = cmd.Run() + ``` + +## 4. Prevent Path Traversal Vulnerabilities + +- : Do not use untrusted input directly in filesystem APIs (os.Open, os.ReadFile, os.Create). + Always sanitize path input to remove traversal elements and enforce a strict allow-list for filenames. +- : If the filename doesn't need to be user-controlled, use a UUID or another randomly generated string instead. This is the most secure method. +- : + ```go + import "path/filepath" + + fileName := r.URL.Query().Get("filename") // Attacker can provide "../../etc/passwd" as a filename + path := filepath.Join("/var/data/", fileName) + data, err := os.ReadFile(path) + ``` +- (Never use user input directly. Sanitize it with filepath.Base and validate with an allow-list): + ```go + import ( + "path/filepath" + "regexp" + ) + + userInput := r.URL.Query().Get("filename") + + // 1. Sanitize the input to get only the final path component. + // removes and turns "../../etc/passwd" into "passwd". + filename := filepath.Base(userInput) + + // 2. Validate the sanitized filename against a strict allow-list. + isValid, _ := regexp.MatchString(`^[A-Za-z0-9_-]{1,200}\.png$`, filename) + + if !isValid { + return + } + ``` + +// 3. Now it's safe to join with the base directory. +safePath := filepath.Join("/var/data/", filename) + ``` + +## 5. Template Safety + +- Use `html/template` for HTML to get auto-escaping. Never use `text/template` for HTML. +- + ```go + t := template.Must(template.New("x").Parse("
{{.UserInput}}
")) + ``` +- + ```go + t := template.Must(htmltemplate.New("x").Parse("
{{.UserInput}}
")) + ``` + +## 6. Log and Error Hygiene + +- Do not log secrets, tokens, personal data, or full request bodies. Redact sensitive fields. Return generic error messages to clients. Use a recover middleware to hide panics. +- + ```go + // Example redaction + logger.Info("login", "user", in.Email, "token", "[redacted]") + + // Recover middleware + func Recover(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer func() { + if rec := recover(); rec != nil { + http.Error(w, "internal error", http.StatusInternalServerError) + } + }() + next.ServeHTTP(w, r) + }) + } + ``` + +## 7. Concurrency and Race Safety + +- Avoid TOCTOU on files and permissions. Guard shared state. +- + ```go + f, err := os.OpenFile(p, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0600) + ``` + +## 8. Cookies and Sessions + +- Set `Secure`, `HttpOnly`, and an appropriate `SameSite`. Do not store secrets in client cookies unless encrypted and signed with a server key. +- + ```go + http.SetCookie(w, &http.Cookie{ + Name: "sid", + Value: token, + Secure: true, + HttpOnly: true, + SameSite: http.SameSiteLaxMode, + Path: "/", + }) + ``` + +## 9. CSRF and CORS + +- Use CSRF protections for state-changing requests in browser-based apps. For CORS, allow list origins and avoid `Access-Control-Allow-Origin: *` with credentials. +- : + ```go + // Pseudocode: only allow https://app.example.com + w.Header().Set("Access-Control-Allow-Origin", "https://app.example.com") + w.Header().Set("Vary", "Origin") + ``` + +## 10. Avoid Reflection, `unsafe`, and Cgo for Untrusted Data + +- Do not use `reflect`, `unsafe`, or Cgo to parse or transform untrusted inputs. Keep type boundaries strict. + +## 11. Operational Hardening + +- Run with least privilege. In containers, avoid root, drop capabilities, mount only what you need. Never expose debug endpoints publicly. +- + ```go + // Exposing pprof on 0.0.0.0 in prod + http.ListenAndServe(":6060", http.DefaultServeMux) + ``` +- + ```go + // Bind pprof to localhost only, or protect with auth and network policy + go func() { _ = http.ListenAndServe("127.0.0.1:6060", nil) }() + ``` +## 12. Parsing XML Securly: +- Use encoding/xml for parsing XML. It does not support DTDs or external entities, so it’s safe against XXE by default. Always limit input size and nesting depth to prevent denial-of-service. +- Never use third-party XML libraries that enable DTDs or external entities. Wrap input with io.LimitReader to cap size. Track nesting depth in custom decoders to prevent stack exhaustion. Validate parsed data against business rules (schemas, required fields, etc.). + +--- + +### Additional Guidance + +- Check inputs as early as possible: validate type, length, format, and restrict to safe values. +- Impose strict size limits on untrusted data such as HTTP requests, file uploads, or archives. +- Avoid reflecting user-controlled content in error messages, HTML, or logs. +- Use `context.Context` to manage timeouts and cancellations consistently across I/O operations. +- Clearly explain any deviations from these rules in the code, along with a follow-up task to remove them. diff --git a/flashring/.cursor/rules/global/security-golang/ssrf-prevention-rules.mdc b/flashring/.cursor/rules/global/security-golang/ssrf-prevention-rules.mdc new file mode 100644 index 00000000..fd8906b7 --- /dev/null +++ b/flashring/.cursor/rules/global/security-golang/ssrf-prevention-rules.mdc @@ -0,0 +1,30 @@ +--- +description: "Rules to prevent Server-Side Request Forgery (SSRF) vulnerabilities" +globs: +alwaysApply: true +--- +# SSRF Prevention + +These rules apply to all code that performs outbound network requests, regardless of language or framework, including generated code. + +All violations must include a clear explanation of which rule was triggered and why, to help developers understand and fix the issue effectively. +Generated code must not violate these rules. If a rule is violated, a comment must be added explaining the issue and suggesting a correction. + +## 1. Do Not Allow User Input to Control Target URLs +- **Rule:** Never use raw or unchecked user input as the destination for outbound HTTP requests. +- **Example (unsafe):** + ```python + requests.get(request.args["url"]) + ``` + +## 2. Block Access to Private/Internal IP Ranges +- **Rule:** Outbound requests must not be allowed to reach `localhost`, `127.0.0.1`, `169.254.0.0/16`, `192.168.0.0/16`, `10.0.0.0/8`, or other internal/reserved ranges. + +## 3. Resolve and Validate Hostnames Before Use +- **Rule:** Perform DNS resolution and validate that the resolved IP is in an allowed range before initiating a request. + +## 4. Restrict Allowed Protocols and Ports +- **Rule:** Only allow HTTP/HTTPS protocols and known-safe ports (e.g., 80, 443). Block access to file URLs, gopher, FTP, or custom handlers. + +## 5. Do Not Forward Authorization Headers Automatically +- **Rule:** Never pass internal tokens, cookies, or auth headers when proxying or forwarding outbound requests unless explicitly scoped and audited. diff --git a/go-sdk/VERSION b/go-sdk/VERSION index 992977ad..0408c30b 100644 --- a/go-sdk/VERSION +++ b/go-sdk/VERSION @@ -1 +1 @@ -v1.1.0 \ No newline at end of file +v1.2.0 \ No newline at end of file diff --git a/go-sdk/go.mod b/go-sdk/go.mod index 76d8dda8..19d67f2d 100644 --- a/go-sdk/go.mod +++ b/go-sdk/go.mod @@ -3,31 +3,72 @@ module github.com/Meesho/BharatMLStack/go-sdk go 1.24.4 require ( + github.com/DataDog/datadog-go/v5 v5.8.3 + github.com/gin-gonic/gin v1.11.0 github.com/rs/zerolog v1.34.0 - github.com/stretchr/testify v1.10.0 + github.com/soheilhy/cmux v0.1.5 + github.com/spf13/viper v1.21.0 + github.com/stretchr/testify v1.11.1 + github.com/x448/float16 v0.8.4 go.etcd.io/etcd/client/v3 v3.5.17 + golang.org/x/net v0.42.0 google.golang.org/grpc v1.68.2 - google.golang.org/protobuf v1.36.6 + google.golang.org/protobuf v1.36.9 ) require ( + github.com/Microsoft/go-winio v0.5.0 // indirect + github.com/bytedance/sonic v1.14.0 // indirect + github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/cloudwego/base64x v0.1.6 // indirect github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.27.0 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-yaml v1.18.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.54.0 // indirect + github.com/sagikazarmark/locafero v0.11.0 // indirect + github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect + github.com/spf13/afero v1.15.0 // indirect + github.com/spf13/cast v1.10.0 // indirect + github.com/spf13/pflag v1.0.10 // indirect github.com/stretchr/objx v0.5.2 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect go.etcd.io/etcd/api/v3 v3.5.17 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.17 // indirect go.uber.org/atomic v1.9.0 // indirect + go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.21.0 // indirect - golang.org/x/net v0.32.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/arch v0.20.0 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/mod v0.26.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.28.0 // indirect + golang.org/x/tools v0.35.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go-sdk/go.sum b/go-sdk/go.sum index 32cd513f..9e87fe57 100644 --- a/go-sdk/go.sum +++ b/go-sdk/go.sum @@ -1,5 +1,15 @@ +github.com/DataDog/datadog-go/v5 v5.8.3 h1:s58CUJ9s8lezjhTNJO/SxkPBv2qZjS3ktpRSqGF5n0s= +github.com/DataDog/datadog-go/v5 v5.8.3/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= +github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= +github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= +github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= +github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= +github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= @@ -8,41 +18,117 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= +github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= +github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= +github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= +github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= +github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= +github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -57,52 +143,70 @@ go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= +golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= +golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= +golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -113,11 +217,12 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a h1: google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= google.golang.org/grpc v1.68.2 h1:EWN8x60kqfCcBXzbfPpEezgdYRZA9JCxtySmCtTUs2E= google.golang.org/grpc v1.68.2/go.mod h1:AOXp0/Lj+nW5pJEgw8KQ6L1Ka+NTyJOABlSgfCrCN5A= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/helix-client/pkg/api/context.go b/go-sdk/pkg/api/context.go similarity index 95% rename from helix-client/pkg/api/context.go rename to go-sdk/pkg/api/context.go index abd61e0b..72333d45 100644 --- a/helix-client/pkg/api/context.go +++ b/go-sdk/pkg/api/context.go @@ -4,7 +4,7 @@ import ( netHttp "net/http" "strconv" - "github.com/Meesho/BharatMLStack/helix-client/pkg/api/http" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/api/http" "github.com/gin-gonic/gin" ) diff --git a/helix-client/pkg/api/error.go b/go-sdk/pkg/api/error.go similarity index 100% rename from helix-client/pkg/api/error.go rename to go-sdk/pkg/api/error.go diff --git a/helix-client/pkg/api/grpc_error.go b/go-sdk/pkg/api/grpc_error.go similarity index 100% rename from helix-client/pkg/api/grpc_error.go rename to go-sdk/pkg/api/grpc_error.go diff --git a/helix-client/pkg/api/http/header.go b/go-sdk/pkg/api/http/header.go similarity index 100% rename from helix-client/pkg/api/http/header.go rename to go-sdk/pkg/api/http/header.go diff --git a/helix-client/pkg/api/http/helper.go b/go-sdk/pkg/api/http/helper.go similarity index 100% rename from helix-client/pkg/api/http/helper.go rename to go-sdk/pkg/api/http/helper.go diff --git a/helix-client/pkg/api/http_grpc_error_mapper.go b/go-sdk/pkg/api/http_grpc_error_mapper.go similarity index 100% rename from helix-client/pkg/api/http_grpc_error_mapper.go rename to go-sdk/pkg/api/http_grpc_error_mapper.go diff --git a/helix-client/pkg/api/request_context.go b/go-sdk/pkg/api/request_context.go similarity index 98% rename from helix-client/pkg/api/request_context.go rename to go-sdk/pkg/api/request_context.go index 2dd813d2..34c8e820 100644 --- a/helix-client/pkg/api/request_context.go +++ b/go-sdk/pkg/api/request_context.go @@ -7,8 +7,8 @@ import ( netHttp "net/http" "strconv" - "github.com/Meesho/BharatMLStack/helix-client/pkg/api/http" - enum "github.com/Meesho/BharatMLStack/helix-client/pkg/enums" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/api/http" + enum "github.com/Meesho/BharatMLStack/go-sdk/pkg/enums" "github.com/gin-gonic/gin" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" diff --git a/helix-client/pkg/api/request_context_test.go b/go-sdk/pkg/api/request_context_test.go similarity index 99% rename from helix-client/pkg/api/request_context_test.go rename to go-sdk/pkg/api/request_context_test.go index ecad973a..773e3448 100644 --- a/helix-client/pkg/api/request_context_test.go +++ b/go-sdk/pkg/api/request_context_test.go @@ -4,13 +4,13 @@ import ( "context" "fmt" - httpHeaders "github.com/Meesho/BharatMLStack/helix-client/pkg/api/http" + httpHeaders "github.com/Meesho/BharatMLStack/go-sdk/pkg/api/http" "net/http" "net/http/httptest" "testing" - enum "github.com/Meesho/BharatMLStack/helix-client/pkg/enums" + enum "github.com/Meesho/BharatMLStack/go-sdk/pkg/enums" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "google.golang.org/grpc/metadata" diff --git a/helix-client/pkg/clients/numerix/adaptor.go b/go-sdk/pkg/clients/numerix/adaptor.go similarity index 96% rename from helix-client/pkg/clients/numerix/adaptor.go rename to go-sdk/pkg/clients/numerix/adaptor.go index 48e88fa7..3f066cca 100644 --- a/helix-client/pkg/clients/numerix/adaptor.go +++ b/go-sdk/pkg/clients/numerix/adaptor.go @@ -5,8 +5,8 @@ import ( "github.com/rs/zerolog/log" - "github.com/Meesho/BharatMLStack/helix-client/pkg/clients/numerix/client/grpc" - "github.com/Meesho/BharatMLStack/helix-client/pkg/datatypeconverter/typeconverter" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/clients/numerix/client/grpc" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/datatypeconverter/typeconverter" ) type IAdapter interface { diff --git a/helix-client/pkg/clients/numerix/adaptor_test.go b/go-sdk/pkg/clients/numerix/adaptor_test.go similarity index 94% rename from helix-client/pkg/clients/numerix/adaptor_test.go rename to go-sdk/pkg/clients/numerix/adaptor_test.go index 082e9953..dd8d082e 100644 --- a/helix-client/pkg/clients/numerix/adaptor_test.go +++ b/go-sdk/pkg/clients/numerix/adaptor_test.go @@ -3,7 +3,7 @@ package numerix import ( "testing" - "github.com/Meesho/BharatMLStack/helix-client/pkg/datatypeconverter/byteorder" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/datatypeconverter/byteorder" "github.com/stretchr/testify/assert" ) diff --git a/helix-client/pkg/clients/numerix/client/grpc/numerix.pb.go b/go-sdk/pkg/clients/numerix/client/grpc/numerix.pb.go similarity index 100% rename from helix-client/pkg/clients/numerix/client/grpc/numerix.pb.go rename to go-sdk/pkg/clients/numerix/client/grpc/numerix.pb.go diff --git a/helix-client/pkg/clients/numerix/client/grpc/numerix_grpc.pb.go b/go-sdk/pkg/clients/numerix/client/grpc/numerix_grpc.pb.go similarity index 100% rename from helix-client/pkg/clients/numerix/client/grpc/numerix_grpc.pb.go rename to go-sdk/pkg/clients/numerix/client/grpc/numerix_grpc.pb.go diff --git a/helix-client/pkg/clients/numerix/client/proto/numerix.proto b/go-sdk/pkg/clients/numerix/client/proto/numerix.proto similarity index 100% rename from helix-client/pkg/clients/numerix/client/proto/numerix.proto rename to go-sdk/pkg/clients/numerix/client/proto/numerix.proto diff --git a/helix-client/pkg/clients/numerix/conf.go b/go-sdk/pkg/clients/numerix/conf.go similarity index 100% rename from helix-client/pkg/clients/numerix/conf.go rename to go-sdk/pkg/clients/numerix/conf.go diff --git a/helix-client/pkg/clients/numerix/init.go b/go-sdk/pkg/clients/numerix/init.go similarity index 100% rename from helix-client/pkg/clients/numerix/init.go rename to go-sdk/pkg/clients/numerix/init.go diff --git a/helix-client/pkg/clients/numerix/models.go b/go-sdk/pkg/clients/numerix/models.go similarity index 88% rename from helix-client/pkg/clients/numerix/models.go rename to go-sdk/pkg/clients/numerix/models.go index aa70b388..3983180c 100644 --- a/helix-client/pkg/clients/numerix/models.go +++ b/go-sdk/pkg/clients/numerix/models.go @@ -1,6 +1,6 @@ package numerix -import "github.com/Meesho/BharatMLStack/helix-client/pkg/clients/numerix/client/grpc" +import "github.com/Meesho/BharatMLStack/go-sdk/pkg/clients/numerix/client/grpc" type NumerixRequest struct { EntityScoreData EntityScoreData `json:"entity_score_data"` diff --git a/helix-client/pkg/clients/numerix/numerix.go b/go-sdk/pkg/clients/numerix/numerix.go similarity index 100% rename from helix-client/pkg/clients/numerix/numerix.go rename to go-sdk/pkg/clients/numerix/numerix.go diff --git a/helix-client/pkg/clients/numerix/v1.go b/go-sdk/pkg/clients/numerix/v1.go similarity index 97% rename from helix-client/pkg/clients/numerix/v1.go rename to go-sdk/pkg/clients/numerix/v1.go index 055fb628..6bc22500 100644 --- a/helix-client/pkg/clients/numerix/v1.go +++ b/go-sdk/pkg/clients/numerix/v1.go @@ -6,9 +6,9 @@ import ( "sync" "time" - "github.com/Meesho/BharatMLStack/helix-client/pkg/clients/numerix/client/grpc" - "github.com/Meesho/BharatMLStack/helix-client/pkg/datatypeconverter/byteorder" - "github.com/Meesho/BharatMLStack/helix-client/pkg/grpcclient" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/clients/numerix/client/grpc" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/datatypeconverter/byteorder" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/grpcclient" "github.com/rs/zerolog/log" metadata "google.golang.org/grpc/metadata" ) diff --git a/helix-client/pkg/clients/predator/README.md b/go-sdk/pkg/clients/predator/README.md similarity index 100% rename from helix-client/pkg/clients/predator/README.md rename to go-sdk/pkg/clients/predator/README.md diff --git a/helix-client/pkg/clients/predator/adaptor.go b/go-sdk/pkg/clients/predator/adaptor.go similarity index 98% rename from helix-client/pkg/clients/predator/adaptor.go rename to go-sdk/pkg/clients/predator/adaptor.go index 3090519c..4e292040 100644 --- a/helix-client/pkg/clients/predator/adaptor.go +++ b/go-sdk/pkg/clients/predator/adaptor.go @@ -8,9 +8,9 @@ import ( "strings" - triton "github.com/Meesho/BharatMLStack/helix-client/pkg/clients/predator/client/grpc" - "github.com/Meesho/BharatMLStack/helix-client/pkg/datatypeconverter/types" - "github.com/Meesho/BharatMLStack/helix-client/pkg/utils" + triton "github.com/Meesho/BharatMLStack/go-sdk/pkg/clients/predator/client/grpc" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/datatypeconverter/types" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/utils" "github.com/rs/zerolog/log" ) diff --git a/helix-client/pkg/clients/predator/client.go b/go-sdk/pkg/clients/predator/client.go similarity index 100% rename from helix-client/pkg/clients/predator/client.go rename to go-sdk/pkg/clients/predator/client.go diff --git a/helix-client/pkg/clients/predator/client/grpc/grpc_service.pb.go b/go-sdk/pkg/clients/predator/client/grpc/grpc_service.pb.go similarity index 100% rename from helix-client/pkg/clients/predator/client/grpc/grpc_service.pb.go rename to go-sdk/pkg/clients/predator/client/grpc/grpc_service.pb.go diff --git a/helix-client/pkg/clients/predator/client/grpc/grpc_service_grpc.pb.go b/go-sdk/pkg/clients/predator/client/grpc/grpc_service_grpc.pb.go similarity index 100% rename from helix-client/pkg/clients/predator/client/grpc/grpc_service_grpc.pb.go rename to go-sdk/pkg/clients/predator/client/grpc/grpc_service_grpc.pb.go diff --git a/helix-client/pkg/clients/predator/client/grpc/health.pb.go b/go-sdk/pkg/clients/predator/client/grpc/health.pb.go similarity index 100% rename from helix-client/pkg/clients/predator/client/grpc/health.pb.go rename to go-sdk/pkg/clients/predator/client/grpc/health.pb.go diff --git a/helix-client/pkg/clients/predator/client/grpc/health_grpc.pb.go b/go-sdk/pkg/clients/predator/client/grpc/health_grpc.pb.go similarity index 100% rename from helix-client/pkg/clients/predator/client/grpc/health_grpc.pb.go rename to go-sdk/pkg/clients/predator/client/grpc/health_grpc.pb.go diff --git a/helix-client/pkg/clients/predator/client/grpc/model_config.pb.go b/go-sdk/pkg/clients/predator/client/grpc/model_config.pb.go similarity index 100% rename from helix-client/pkg/clients/predator/client/grpc/model_config.pb.go rename to go-sdk/pkg/clients/predator/client/grpc/model_config.pb.go diff --git a/helix-client/pkg/clients/predator/client/proto/grpc_service.proto b/go-sdk/pkg/clients/predator/client/proto/grpc_service.proto similarity index 100% rename from helix-client/pkg/clients/predator/client/proto/grpc_service.proto rename to go-sdk/pkg/clients/predator/client/proto/grpc_service.proto diff --git a/helix-client/pkg/clients/predator/client/proto/health.proto b/go-sdk/pkg/clients/predator/client/proto/health.proto similarity index 100% rename from helix-client/pkg/clients/predator/client/proto/health.proto rename to go-sdk/pkg/clients/predator/client/proto/health.proto diff --git a/helix-client/pkg/clients/predator/client/proto/model_config.proto b/go-sdk/pkg/clients/predator/client/proto/model_config.proto similarity index 100% rename from helix-client/pkg/clients/predator/client/proto/model_config.proto rename to go-sdk/pkg/clients/predator/client/proto/model_config.proto diff --git a/helix-client/pkg/clients/predator/config.go b/go-sdk/pkg/clients/predator/config.go similarity index 100% rename from helix-client/pkg/clients/predator/config.go rename to go-sdk/pkg/clients/predator/config.go diff --git a/helix-client/pkg/clients/predator/init.go b/go-sdk/pkg/clients/predator/init.go similarity index 100% rename from helix-client/pkg/clients/predator/init.go rename to go-sdk/pkg/clients/predator/init.go diff --git a/helix-client/pkg/clients/predator/models.go b/go-sdk/pkg/clients/predator/models.go similarity index 100% rename from helix-client/pkg/clients/predator/models.go rename to go-sdk/pkg/clients/predator/models.go diff --git a/helix-client/pkg/clients/predator/v1.go b/go-sdk/pkg/clients/predator/v1.go similarity index 98% rename from helix-client/pkg/clients/predator/v1.go rename to go-sdk/pkg/clients/predator/v1.go index 7bfae8f4..c7169550 100644 --- a/helix-client/pkg/clients/predator/v1.go +++ b/go-sdk/pkg/clients/predator/v1.go @@ -5,9 +5,9 @@ import ( "fmt" "time" - triton "github.com/Meesho/BharatMLStack/helix-client/pkg/clients/predator/client/grpc" - "github.com/Meesho/BharatMLStack/helix-client/pkg/grpcclient" - "github.com/Meesho/BharatMLStack/helix-client/pkg/metric" + triton "github.com/Meesho/BharatMLStack/go-sdk/pkg/clients/predator/client/grpc" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/grpcclient" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/metric" "github.com/rs/zerolog/log" "google.golang.org/grpc/metadata" ) diff --git a/helix-client/pkg/clients/skye/client/grpc/skye.pb.go b/go-sdk/pkg/clients/skye/client/grpc/skye.pb.go similarity index 100% rename from helix-client/pkg/clients/skye/client/grpc/skye.pb.go rename to go-sdk/pkg/clients/skye/client/grpc/skye.pb.go diff --git a/helix-client/pkg/clients/skye/client/grpc/skye_grpc.pb.go b/go-sdk/pkg/clients/skye/client/grpc/skye_grpc.pb.go similarity index 100% rename from helix-client/pkg/clients/skye/client/grpc/skye_grpc.pb.go rename to go-sdk/pkg/clients/skye/client/grpc/skye_grpc.pb.go diff --git a/helix-client/pkg/clients/skye/client/proto/skye.proto b/go-sdk/pkg/clients/skye/client/proto/skye.proto similarity index 100% rename from helix-client/pkg/clients/skye/client/proto/skye.proto rename to go-sdk/pkg/clients/skye/client/proto/skye.proto diff --git a/helix-client/pkg/clients/skye/conf.go b/go-sdk/pkg/clients/skye/conf.go similarity index 100% rename from helix-client/pkg/clients/skye/conf.go rename to go-sdk/pkg/clients/skye/conf.go diff --git a/helix-client/pkg/clients/skye/init.go b/go-sdk/pkg/clients/skye/init.go similarity index 100% rename from helix-client/pkg/clients/skye/init.go rename to go-sdk/pkg/clients/skye/init.go diff --git a/helix-client/pkg/clients/skye/models.go b/go-sdk/pkg/clients/skye/models.go similarity index 60% rename from helix-client/pkg/clients/skye/models.go rename to go-sdk/pkg/clients/skye/models.go index 3ff2c304..ffca910e 100644 --- a/helix-client/pkg/clients/skye/models.go +++ b/go-sdk/pkg/clients/skye/models.go @@ -1,6 +1,6 @@ package skye -import "github.com/Meesho/BharatMLStack/helix-client/pkg/grpcclient" +import "github.com/Meesho/BharatMLStack/go-sdk/pkg/grpcclient" type ClientV1 struct { ClientConfigs *ClientConfig diff --git a/helix-client/pkg/clients/skye/skye.go b/go-sdk/pkg/clients/skye/skye.go similarity index 82% rename from helix-client/pkg/clients/skye/skye.go rename to go-sdk/pkg/clients/skye/skye.go index 776aa9a8..c02c7d22 100644 --- a/helix-client/pkg/clients/skye/skye.go +++ b/go-sdk/pkg/clients/skye/skye.go @@ -1,7 +1,7 @@ package skye import ( - "github.com/Meesho/BharatMLStack/helix-client/pkg/clients/skye/client/grpc" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/clients/skye/client/grpc" ) type SkyeClient interface { diff --git a/helix-client/pkg/clients/skye/v1.go b/go-sdk/pkg/clients/skye/v1.go similarity index 97% rename from helix-client/pkg/clients/skye/v1.go rename to go-sdk/pkg/clients/skye/v1.go index 4c4a9244..ca5f93ea 100644 --- a/helix-client/pkg/clients/skye/v1.go +++ b/go-sdk/pkg/clients/skye/v1.go @@ -6,8 +6,8 @@ import ( "sync" "time" - grpc2 "github.com/Meesho/BharatMLStack/helix-client/pkg/clients/skye/client/grpc" - "github.com/Meesho/BharatMLStack/helix-client/pkg/grpcclient" + grpc2 "github.com/Meesho/BharatMLStack/go-sdk/pkg/clients/skye/client/grpc" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/grpcclient" "github.com/rs/zerolog/log" "github.com/spf13/viper" "google.golang.org/grpc/metadata" diff --git a/helix-client/pkg/clients/skye/v1_test.go b/go-sdk/pkg/clients/skye/v1_test.go similarity index 99% rename from helix-client/pkg/clients/skye/v1_test.go rename to go-sdk/pkg/clients/skye/v1_test.go index 098275c1..603cb9ce 100644 --- a/helix-client/pkg/clients/skye/v1_test.go +++ b/go-sdk/pkg/clients/skye/v1_test.go @@ -47,7 +47,7 @@ package skye // viper.Set("SKYE_CLIENT_V1_PORT", "80") // viper.Set("SKYE_CLIENT_V1_DEADLINE_MS", 50000) // viper.Set("SKYE_CLIENT_V1_AUTH_TOKEN", "pre-prod") -// viper.Set("APP_NAME", "skye-helix-client") +// viper.Set("APP_NAME", "skye-go-sdk") // testcases := []struct { // name string // request *SimilarCandidateRequest diff --git a/helix-client/pkg/datatypeconverter/byteorder/pack_test.go b/go-sdk/pkg/datatypeconverter/byteorder/pack_test.go similarity index 100% rename from helix-client/pkg/datatypeconverter/byteorder/pack_test.go rename to go-sdk/pkg/datatypeconverter/byteorder/pack_test.go diff --git a/helix-client/pkg/datatypeconverter/byteorder/system.go b/go-sdk/pkg/datatypeconverter/byteorder/system.go similarity index 99% rename from helix-client/pkg/datatypeconverter/byteorder/system.go rename to go-sdk/pkg/datatypeconverter/byteorder/system.go index 74178382..87e640d6 100644 --- a/helix-client/pkg/datatypeconverter/byteorder/system.go +++ b/go-sdk/pkg/datatypeconverter/byteorder/system.go @@ -8,8 +8,8 @@ import ( "math" "unsafe" - "github.com/Meesho/BharatMLStack/helix-client/pkg/datatypeconverter/float8" - "github.com/Meesho/BharatMLStack/helix-client/pkg/datatypeconverter/types" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/datatypeconverter/float8" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/datatypeconverter/types" "github.com/x448/float16" ) diff --git a/helix-client/pkg/datatypeconverter/byteorder/system_test.go b/go-sdk/pkg/datatypeconverter/byteorder/system_test.go similarity index 100% rename from helix-client/pkg/datatypeconverter/byteorder/system_test.go rename to go-sdk/pkg/datatypeconverter/byteorder/system_test.go diff --git a/helix-client/pkg/datatypeconverter/byteorder/vector_test.go b/go-sdk/pkg/datatypeconverter/byteorder/vector_test.go similarity index 100% rename from helix-client/pkg/datatypeconverter/byteorder/vector_test.go rename to go-sdk/pkg/datatypeconverter/byteorder/vector_test.go diff --git a/helix-client/pkg/datatypeconverter/float8/float8_e4m3.go b/go-sdk/pkg/datatypeconverter/float8/float8_e4m3.go similarity index 100% rename from helix-client/pkg/datatypeconverter/float8/float8_e4m3.go rename to go-sdk/pkg/datatypeconverter/float8/float8_e4m3.go diff --git a/helix-client/pkg/datatypeconverter/float8/float8_e4m3_bench_test.go b/go-sdk/pkg/datatypeconverter/float8/float8_e4m3_bench_test.go similarity index 100% rename from helix-client/pkg/datatypeconverter/float8/float8_e4m3_bench_test.go rename to go-sdk/pkg/datatypeconverter/float8/float8_e4m3_bench_test.go diff --git a/helix-client/pkg/datatypeconverter/float8/float8_e4m3_test.go b/go-sdk/pkg/datatypeconverter/float8/float8_e4m3_test.go similarity index 100% rename from helix-client/pkg/datatypeconverter/float8/float8_e4m3_test.go rename to go-sdk/pkg/datatypeconverter/float8/float8_e4m3_test.go diff --git a/helix-client/pkg/datatypeconverter/float8/float8_e5m2.go b/go-sdk/pkg/datatypeconverter/float8/float8_e5m2.go similarity index 100% rename from helix-client/pkg/datatypeconverter/float8/float8_e5m2.go rename to go-sdk/pkg/datatypeconverter/float8/float8_e5m2.go diff --git a/helix-client/pkg/datatypeconverter/float8/float8_e5m2_bench_test.go b/go-sdk/pkg/datatypeconverter/float8/float8_e5m2_bench_test.go similarity index 100% rename from helix-client/pkg/datatypeconverter/float8/float8_e5m2_bench_test.go rename to go-sdk/pkg/datatypeconverter/float8/float8_e5m2_bench_test.go diff --git a/helix-client/pkg/datatypeconverter/float8/float8_e5m2_test.go b/go-sdk/pkg/datatypeconverter/float8/float8_e5m2_test.go similarity index 100% rename from helix-client/pkg/datatypeconverter/float8/float8_e5m2_test.go rename to go-sdk/pkg/datatypeconverter/float8/float8_e5m2_test.go diff --git a/helix-client/pkg/datatypeconverter/typeconverter/tyeconverter.go b/go-sdk/pkg/datatypeconverter/typeconverter/tyeconverter.go similarity index 99% rename from helix-client/pkg/datatypeconverter/typeconverter/tyeconverter.go rename to go-sdk/pkg/datatypeconverter/typeconverter/tyeconverter.go index 3ca8df3f..2599c26e 100644 --- a/helix-client/pkg/datatypeconverter/typeconverter/tyeconverter.go +++ b/go-sdk/pkg/datatypeconverter/typeconverter/tyeconverter.go @@ -5,8 +5,8 @@ import ( "strconv" "strings" - "github.com/Meesho/BharatMLStack/helix-client/pkg/datatypeconverter/byteorder" - "github.com/Meesho/BharatMLStack/helix-client/pkg/datatypeconverter/types" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/datatypeconverter/byteorder" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/datatypeconverter/types" ) // BytesToString converts byte data to string based on the specified data type diff --git a/helix-client/pkg/datatypeconverter/typeconverter/tyeconverter_test.go b/go-sdk/pkg/datatypeconverter/typeconverter/tyeconverter_test.go similarity index 99% rename from helix-client/pkg/datatypeconverter/typeconverter/tyeconverter_test.go rename to go-sdk/pkg/datatypeconverter/typeconverter/tyeconverter_test.go index 2180e999..bafc2ebe 100644 --- a/helix-client/pkg/datatypeconverter/typeconverter/tyeconverter_test.go +++ b/go-sdk/pkg/datatypeconverter/typeconverter/tyeconverter_test.go @@ -6,7 +6,7 @@ import ( "strconv" "testing" - "github.com/Meesho/BharatMLStack/helix-client/pkg/datatypeconverter/byteorder" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/datatypeconverter/byteorder" ) func TestMain(m *testing.M) { diff --git a/helix-client/pkg/datatypeconverter/types/data_type.go b/go-sdk/pkg/datatypeconverter/types/data_type.go similarity index 100% rename from helix-client/pkg/datatypeconverter/types/data_type.go rename to go-sdk/pkg/datatypeconverter/types/data_type.go diff --git a/helix-client/pkg/datatypeconverter/types/data_type_test.go b/go-sdk/pkg/datatypeconverter/types/data_type_test.go similarity index 100% rename from helix-client/pkg/datatypeconverter/types/data_type_test.go rename to go-sdk/pkg/datatypeconverter/types/data_type_test.go diff --git a/helix-client/pkg/enums/client_type.go b/go-sdk/pkg/enums/client_type.go similarity index 100% rename from helix-client/pkg/enums/client_type.go rename to go-sdk/pkg/enums/client_type.go diff --git a/helix-client/pkg/enums/user_context.go b/go-sdk/pkg/enums/user_context.go similarity index 100% rename from helix-client/pkg/enums/user_context.go rename to go-sdk/pkg/enums/user_context.go diff --git a/helix-client/pkg/grpc/grpcframework.go b/go-sdk/pkg/grpc/grpcframework.go similarity index 96% rename from helix-client/pkg/grpc/grpcframework.go rename to go-sdk/pkg/grpc/grpcframework.go index ca43d166..811cd66e 100644 --- a/helix-client/pkg/grpc/grpcframework.go +++ b/go-sdk/pkg/grpc/grpcframework.go @@ -6,8 +6,8 @@ import ( "strconv" "sync" - "github.com/Meesho/BharatMLStack/helix-client/pkg/httpframework" - "github.com/Meesho/BharatMLStack/helix-client/pkg/middleware" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/httpframework" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/middleware" "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" "github.com/soheilhy/cmux" diff --git a/helix-client/pkg/grpc/grpcframework_test.go b/go-sdk/pkg/grpc/grpcframework_test.go similarity index 99% rename from helix-client/pkg/grpc/grpcframework_test.go rename to go-sdk/pkg/grpc/grpcframework_test.go index 861287ba..96ae3b87 100644 --- a/helix-client/pkg/grpc/grpcframework_test.go +++ b/go-sdk/pkg/grpc/grpcframework_test.go @@ -8,7 +8,7 @@ import ( "testing" "time" - "github.com/Meesho/BharatMLStack/helix-client/pkg/httpframework" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/httpframework" "github.com/spf13/viper" "github.com/stretchr/testify/assert" diff --git a/helix-client/pkg/grpc/options_util.go b/go-sdk/pkg/grpc/options_util.go similarity index 100% rename from helix-client/pkg/grpc/options_util.go rename to go-sdk/pkg/grpc/options_util.go diff --git a/helix-client/pkg/grpcclient/grpc.go b/go-sdk/pkg/grpcclient/grpc.go similarity index 98% rename from helix-client/pkg/grpcclient/grpc.go rename to go-sdk/pkg/grpcclient/grpc.go index f0c5d7c3..7490d1d6 100644 --- a/helix-client/pkg/grpcclient/grpc.go +++ b/go-sdk/pkg/grpcclient/grpc.go @@ -5,7 +5,7 @@ import ( "errors" "time" - "github.com/Meesho/BharatMLStack/helix-client/pkg/metric" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/metric" "github.com/rs/zerolog/log" "github.com/spf13/viper" "golang.org/x/net/context" diff --git a/helix-client/pkg/grpcclient/grpc_test.go b/go-sdk/pkg/grpcclient/grpc_test.go similarity index 100% rename from helix-client/pkg/grpcclient/grpc_test.go rename to go-sdk/pkg/grpcclient/grpc_test.go diff --git a/helix-client/pkg/httpframework/httpframework.go b/go-sdk/pkg/httpframework/httpframework.go similarity index 94% rename from helix-client/pkg/httpframework/httpframework.go rename to go-sdk/pkg/httpframework/httpframework.go index 977da553..e88a1129 100644 --- a/helix-client/pkg/httpframework/httpframework.go +++ b/go-sdk/pkg/httpframework/httpframework.go @@ -4,7 +4,7 @@ import ( "os" "sync" - "github.com/Meesho/BharatMLStack/helix-client/pkg/middleware" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/middleware" "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" "github.com/spf13/viper" diff --git a/helix-client/pkg/httpframework/httpframework_test.go b/go-sdk/pkg/httpframework/httpframework_test.go similarity index 100% rename from helix-client/pkg/httpframework/httpframework_test.go rename to go-sdk/pkg/httpframework/httpframework_test.go diff --git a/helix-client/pkg/metric/metric.go b/go-sdk/pkg/metric/metric.go similarity index 100% rename from helix-client/pkg/metric/metric.go rename to go-sdk/pkg/metric/metric.go diff --git a/helix-client/pkg/metric/tag.go b/go-sdk/pkg/metric/tag.go similarity index 100% rename from helix-client/pkg/metric/tag.go rename to go-sdk/pkg/metric/tag.go diff --git a/helix-client/pkg/metric/tag_test.go b/go-sdk/pkg/metric/tag_test.go similarity index 100% rename from helix-client/pkg/metric/tag_test.go rename to go-sdk/pkg/metric/tag_test.go diff --git a/helix-client/pkg/middleware/grpclogger.go b/go-sdk/pkg/middleware/grpclogger.go similarity index 96% rename from helix-client/pkg/middleware/grpclogger.go rename to go-sdk/pkg/middleware/grpclogger.go index 5a6e0fbc..7a362aab 100644 --- a/helix-client/pkg/middleware/grpclogger.go +++ b/go-sdk/pkg/middleware/grpclogger.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/Meesho/BharatMLStack/helix-client/pkg/metric" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/metric" "github.com/rs/zerolog/log" "google.golang.org/grpc" "google.golang.org/grpc/codes" diff --git a/helix-client/pkg/middleware/grpcrecovery.go b/go-sdk/pkg/middleware/grpcrecovery.go similarity index 100% rename from helix-client/pkg/middleware/grpcrecovery.go rename to go-sdk/pkg/middleware/grpcrecovery.go diff --git a/helix-client/pkg/middleware/httplogger.go b/go-sdk/pkg/middleware/httplogger.go similarity index 91% rename from helix-client/pkg/middleware/httplogger.go rename to go-sdk/pkg/middleware/httplogger.go index d4c7ba55..160742fc 100644 --- a/helix-client/pkg/middleware/httplogger.go +++ b/go-sdk/pkg/middleware/httplogger.go @@ -7,8 +7,8 @@ import ( "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" - "github.com/Meesho/BharatMLStack/helix-client/pkg/api/http" - "github.com/Meesho/BharatMLStack/helix-client/pkg/metric" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/api/http" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/metric" ) // HTTPLogger logs the request diff --git a/helix-client/pkg/middleware/httplogger_test.go b/go-sdk/pkg/middleware/httplogger_test.go similarity index 97% rename from helix-client/pkg/middleware/httplogger_test.go rename to go-sdk/pkg/middleware/httplogger_test.go index 72aa28ec..887eb516 100644 --- a/helix-client/pkg/middleware/httplogger_test.go +++ b/go-sdk/pkg/middleware/httplogger_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - http2 "github.com/Meesho/BharatMLStack/helix-client/pkg/api/http" + http2 "github.com/Meesho/BharatMLStack/go-sdk/pkg/api/http" "github.com/gin-gonic/gin" "github.com/rs/zerolog" "github.com/rs/zerolog/log" diff --git a/helix-client/pkg/middleware/httprecovery.go b/go-sdk/pkg/middleware/httprecovery.go similarity index 92% rename from helix-client/pkg/middleware/httprecovery.go rename to go-sdk/pkg/middleware/httprecovery.go index 69f3e3c4..384e8987 100644 --- a/helix-client/pkg/middleware/httprecovery.go +++ b/go-sdk/pkg/middleware/httprecovery.go @@ -4,7 +4,7 @@ import ( "fmt" "runtime/debug" - "github.com/Meesho/BharatMLStack/helix-client/pkg/api" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/api" "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" ) diff --git a/helix-client/pkg/system/global.go b/go-sdk/pkg/system/global.go similarity index 100% rename from helix-client/pkg/system/global.go rename to go-sdk/pkg/system/global.go diff --git a/helix-client/pkg/utils/byte_utils.go b/go-sdk/pkg/utils/byte_utils.go similarity index 98% rename from helix-client/pkg/utils/byte_utils.go rename to go-sdk/pkg/utils/byte_utils.go index fd32d5e0..8415d329 100644 --- a/helix-client/pkg/utils/byte_utils.go +++ b/go-sdk/pkg/utils/byte_utils.go @@ -6,7 +6,7 @@ import ( "errors" "reflect" - "github.com/Meesho/BharatMLStack/helix-client/pkg/system" + "github.com/Meesho/BharatMLStack/go-sdk/pkg/system" "github.com/rs/zerolog/log" ) diff --git a/helix-client/pkg/utils/byte_utils_test.go b/go-sdk/pkg/utils/byte_utils_test.go similarity index 100% rename from helix-client/pkg/utils/byte_utils_test.go rename to go-sdk/pkg/utils/byte_utils_test.go diff --git a/helix-client/pkg/utils/empty_utils.go b/go-sdk/pkg/utils/empty_utils.go similarity index 100% rename from helix-client/pkg/utils/empty_utils.go rename to go-sdk/pkg/utils/empty_utils.go diff --git a/helix-client/pkg/utils/empty_utils_test.go b/go-sdk/pkg/utils/empty_utils_test.go similarity index 100% rename from helix-client/pkg/utils/empty_utils_test.go rename to go-sdk/pkg/utils/empty_utils_test.go diff --git a/helix-client/pkg/utils/slice_utils.go b/go-sdk/pkg/utils/slice_utils.go similarity index 100% rename from helix-client/pkg/utils/slice_utils.go rename to go-sdk/pkg/utils/slice_utils.go diff --git a/helix-client/pkg/utils/slice_utils_test.go b/go-sdk/pkg/utils/slice_utils_test.go similarity index 100% rename from helix-client/pkg/utils/slice_utils_test.go rename to go-sdk/pkg/utils/slice_utils_test.go diff --git a/helix-client/README.md b/helix-client/README.md deleted file mode 100644 index 8e7b2a3f..00000000 --- a/helix-client/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# helix-clients - -### Environment Variables -```shell -HELIX_CLIENT_ENABLED=true -HELIX_CLIENT_API_AUTH_TOKEN= -HELIX_CLIENT_CONFIG_REFRESH_INTERVAL_IN_MINUTES=10 -HELIX_CLIENT_CONFIG_INIT_HARD_FAILURE=false -HELIX_CLIENT_ENVIRONMENT=PROD - - -HELIX_CLIENT_CONN_CONF_COUNT=1 - -HELIX_CLIENT_CONN_CONF_ID=1 -HELIX_CLIENT_CONN_CONF_1_CONFIG_ID=pdp-organic-1,pdp-organic-2 -HELIX_CLIENT_CONN_CONF_1_SERVICE=MODEL_PROXY -HELIX_CLIENT_CONN_CONF_1_CONN_PROTOCOL=HTTP1 -HELIX_CLIENT_CONN_CONF_1_TIMEOUT=200 -HELIX_CLIENT_CONN_CONF_1_MAX_IDLE_CONN=200 -HELIX_CLIENT_CONN_CONF_1_MAX_IDLE_CONN_PER_HOST=200 -HELIX_CLIENT_CONN_CONF_1_IDLE_CONN_TIMEOUT=200 -OR -HELIX_CLIENT_CONN_CONF_ID=1 -HELIX_CLIENT_CONN_CONF_1_CONFIG_ID=pdp-organic-3,pdp-organic-4 -HELIX_CLIENT_CONN_CONF_1_SERVICE=MODEL_PROXY -HELIX_CLIENT_CONN_CONF_1_CONN_PROTOCOL=GRPC -HELIX_CLIENT_CONN_CONF_1_DEADLINE=200 -HELIX_CLIENT_CONN_CONF_1_PLAINTEXT=true -HELIX_CLIENT_CONN_CONF_1_CHAN_ALGO=round-robin -HELIX_CLIENT_CONN_CONF_1_KEEP_ALIVE_TIME=200 -HELIX_CLIENT_CONN_CONF_1_KEEP_ALIVE_WITHOUT_CALLS=true -HELIX_CLIENT_CONN_CONF_1_IDLE_CONN_TIME_OUT=200 -``` diff --git a/helix-client/VERSION b/helix-client/VERSION deleted file mode 100644 index 60453e69..00000000 --- a/helix-client/VERSION +++ /dev/null @@ -1 +0,0 @@ -v1.0.0 \ No newline at end of file diff --git a/helix-client/go.mod b/helix-client/go.mod deleted file mode 100644 index cfd1c694..00000000 --- a/helix-client/go.mod +++ /dev/null @@ -1,68 +0,0 @@ -module github.com/Meesho/BharatMLStack/helix-client - -go 1.24.4 - -require github.com/rs/zerolog v1.33.0 - -require ( - github.com/DataDog/datadog-go/v5 v5.5.0 - github.com/gin-gonic/gin v1.11.0 - github.com/soheilhy/cmux v0.1.5 - github.com/spf13/viper v1.16.0 - github.com/stretchr/testify v1.11.1 - github.com/x448/float16 v0.8.4 - golang.org/x/net v0.43.0 - google.golang.org/grpc v1.75.0 - google.golang.org/protobuf v1.36.9 -) - -require ( - github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/bytedance/sonic v1.14.0 // indirect - github.com/bytedance/sonic/loader v0.3.0 // indirect - github.com/cloudwego/base64x v0.1.6 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.8 // indirect - github.com/gin-contrib/sse v1.1.0 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.27.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect - github.com/goccy/go-yaml v1.18.0 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.3.0 // indirect - github.com/leodido/go-urn v1.4.0 // indirect - github.com/magiconair/properties v1.8.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.2.4 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/quic-go/qpack v0.5.1 // indirect - github.com/quic-go/quic-go v0.54.0 // indirect - github.com/rogpeppe/go-internal v1.13.1 // indirect - github.com/spf13/afero v1.9.5 // indirect - github.com/spf13/cast v1.5.1 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/subosito/gotenv v1.4.2 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.3.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.uber.org/mock v0.5.0 // indirect - golang.org/x/arch v0.20.0 // indirect - golang.org/x/crypto v0.41.0 // indirect - golang.org/x/mod v0.26.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/tools v0.35.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/helix-client/go.sum b/helix-client/go.sum deleted file mode 100644 index 43bca6d8..00000000 --- a/helix-client/go.sum +++ /dev/null @@ -1,613 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DataDog/datadog-go/v5 v5.5.0 h1:G5KHeB8pWBNXT4Jtw0zAkhdxEAWSpWH00geHI6LDrKU= -github.com/DataDog/datadog-go/v5 v5.5.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= -github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= -github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= -github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= -github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= -github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= -github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= -github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= -github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= -github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= -github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= -github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= -github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= -github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= -github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= -github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= -github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= -github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= -github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= -github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= -github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= -github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= -github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= -github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= -github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= -github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= -github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= -go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= -go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= -golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= -golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= -golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= -golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= -google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= -google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/manual-release.sh b/manual-release.sh index c39da4f1..dbaf398a 100755 --- a/manual-release.sh +++ b/manual-release.sh @@ -11,7 +11,7 @@ CYAN='\033[0;36m' NC='\033[0m' # No Color # Available modules for release -AVAILABLE_MODULES=("horizon" "trufflebox-ui" "numerix" "online-feature-store" "go-sdk" "py-sdk" "helix-client" "inferflow" "skye") +AVAILABLE_MODULES=("horizon" "trufflebox-ui" "numerix" "online-feature-store" "go-sdk" "py-sdk" "inferflow" "skye") # Python SDK subdirectories PY_SDK_MODULES=("bharatml_commons" "grpc_feature_client" "spark_feature_push_client") @@ -170,9 +170,6 @@ trigger_workflow() { "py-sdk") workflow_file="release-py-sdk.yml" ;; - "helix-client") - workflow_file="release-helix-client.yml" - ;; "inferflow") workflow_file="release-inferflow.yml" ;; diff --git a/quick-start/PREDATOR_SETUP.md b/quick-start/PREDATOR_SETUP.md index f0b96447..5ae2915d 100644 --- a/quick-start/PREDATOR_SETUP.md +++ b/quick-start/PREDATOR_SETUP.md @@ -1105,21 +1105,21 @@ kubectl -n prd-predator port-forward svc/prd-predator 8090:80 & # Step 3: Test gRPC access from your host machine # Predator exposes Triton gRPC on port 8001 (service port 80 -> targetPort 8001) grpcurl -plaintext \ - -import-path helix-client/pkg/clients/predator/client/proto \ + -import-path go-sdk/pkg/clients/predator/client/proto \ -proto grpc_service.proto \ -d '{}' \ localhost:8090 inference.GRPCInferenceService/ServerLive # Test server readiness grpcurl -plaintext \ - -import-path helix-client/pkg/clients/predator/client/proto \ + -import-path go-sdk/pkg/clients/predator/client/proto \ -proto grpc_service.proto \ -d '{}' \ localhost:8090 inference.GRPCInferenceService/ServerReady # List available services grpcurl -plaintext \ - -import-path helix-client/pkg/clients/predator/client/proto \ + -import-path go-sdk/pkg/clients/predator/client/proto \ -proto grpc_service.proto \ localhost:8090 list diff --git a/quick-start/docker-compose.yml b/quick-start/docker-compose.yml index d40b5856..6bff1db4 100644 --- a/quick-start/docker-compose.yml +++ b/quick-start/docker-compose.yml @@ -234,6 +234,7 @@ services: - STORAGE_SCYLLA_1_TIMEOUT_IN_MS=300000 - STORAGE_SCYLLA_1_USERNAME= - STORAGE_SCYLLA_1_PASSWORD= + - STORAGE_SCYLLA_1_MAJOR_VERSION=5 - STORAGE_SCYLLA_1_SCYLLA_VERSION=5 - STORAGE_SCYLLA_ACTIVE_CONFIG_IDS=1 - P2P_CACHE_5_ENABLED=true @@ -326,6 +327,7 @@ services: - STORAGE_SCYLLA_1_TIMEOUT_IN_MS=300000 - STORAGE_SCYLLA_1_USERNAME= - STORAGE_SCYLLA_1_PASSWORD= + - STORAGE_SCYLLA_1_MAJOR_VERSION=5 - STORAGE_SCYLLA_1_SCYLLA_VERSION=5 - STORAGE_SCYLLA_ACTIVE_CONFIG_IDS=1 # Etcd Configuration @@ -502,7 +504,7 @@ services: restart: "no" numerix: - image: numerix:${NUMERIX_VERSION:-latest} + image: ghcr.io/meesho/numerix:${NUMERIX_VERSION:-latest} container_name: numerix ports: - "8083:8083" diff --git a/quick-start/setup-predator-k8s.sh b/quick-start/setup-predator-k8s.sh index 53fa211b..8f8e8288 100755 --- a/quick-start/setup-predator-k8s.sh +++ b/quick-start/setup-predator-k8s.sh @@ -1781,7 +1781,7 @@ print_summary() { echo "2. Access Predator service directly via port-forward:" echo " kubectl -n prd-predator port-forward svc/prd-predator 8090:80" echo " Then test with:" - echo " grpcurl -plaintext -import-path helix-client/pkg/clients/predator/client/proto \\" + echo " grpcurl -plaintext -import-path go-sdk/pkg/clients/predator/client/proto \\" echo " -proto grpc_service.proto -d '{}' \\" echo " localhost:8090 inference.GRPCInferenceService/ServerLive" echo "" diff --git a/quick-start/stop.sh b/quick-start/stop.sh index 8df92ecd..2e8dac69 100755 --- a/quick-start/stop.sh +++ b/quick-start/stop.sh @@ -67,7 +67,7 @@ remove_images() { echo "🖼️ Removing Docker images..." # List of image patterns to remove - IMAGES=("ghcr.io/meesho/onfs-consumer" "ghcr.io/meesho/trufflebox-ui" "numerix" "ghcr.io/meesho/horizon" "ghcr.io/meesho/onfs-api-server" "ghcr.io/meesho/inferflow" "ghcr.io/meesho/skye-admin" "ghcr.io/meesho/skye-consumers" "ghcr.io/meesho/skye-serving" "provectuslabs/kafka-ui" "apache/kafka" "quay.io/coreos/etcd" "tzfun/etcd-workbench" "redis" "mysql" "scylladb/scylla" "workspace-db-init" "alpine") + IMAGES=("ghcr.io/meesho/onfs-consumer" "ghcr.io/meesho/trufflebox-ui" "ghcr.io/meesho/numerix" "ghcr.io/meesho/horizon" "ghcr.io/meesho/onfs-api-server" "ghcr.io/meesho/inferflow" "ghcr.io/meesho/skye-admin" "ghcr.io/meesho/skye-consumers" "ghcr.io/meesho/skye-serving" "provectuslabs/kafka-ui" "apache/kafka" "quay.io/coreos/etcd" "tzfun/etcd-workbench" "redis" "mysql" "scylladb/scylla" "workspace-db-init" "alpine") for image_pattern in "${IMAGES[@]}"; do # Find images that match the pattern